Creating a custom plugin in Zend Framework 2 is fairly easy, but many time I just need the direct access to Zend Service Manager.

Create new Plugin:

Declare the plugin in the module.config.php file

<?php

return array(
/* ..... */
    'controller_plugins' => array (
        'invokables' => array(
            'myplugin' => 'Acme\Controller\Plugin\MyPlugin',
        ),
    ),
);

Create the Plugin

Create a new file in the plugins folder, I choosed the folder Plugin inside the Controller folder,
you can choose whatever location you want, but you have to change the configuration above to match this location.

namespace Acme\Controller\Plugin\MyPlugin;

use Zend\Mvc\Controller\Plugin\AbstractPlugin;
use Zend\ServiceManager\ServiceLocatorInterface;
use Zend\ServiceManager\ServiceLocatorAwareInterface;

/**
 * Class MyPlugin
 * @package Acme\Controller\Plugin
 */
class MyPlugin extends AbstractPlugin implements ServiceLocatorAwareInterface
{
    /**
     * @var ServiceLocatorInterface
     */
    private $serviceLocator;

    /**
     * @param ServiceLocatorInterface $serviceLocator
     */
    public function setServiceLocator(ServiceLocatorInterface $serviceLocator)
    {
        $this->serviceLocator = $serviceLocator;
    }

    /**
     * @return ServiceLocatorInterface|\Zend\Mvc\Controller\PluginManager
     */
    public function getServiceLocator()
    {
        return $this->serviceLocator;
    }

    public function __invoke()
    {
        /* you plugin code here */
    }
}

Accessing Service Manager

You can access the Service Manager in the __invoke method, the ServiceLocator injected in MyPlugin is the PluginManager, not the ServiceManager, that' why you need to call getServiceLocator() method twice to get the ServiceManager.

public function __invoke()
{
$serviceManager = $this->getServiceLocator()->getServiceLocator();
    $config = $serviceManager->get('config');
}