statement

Declaration face

The Aspect class is similar to any other normal bean and may have methods and fields just like any other class, but they will use the @Aspect annotation as follows:

 use Swoft\Aop\Annotation\Mapping\Aspect;

/**
 * Class DemoAspect
 *
 * @since 2.0
 *
 * @Aspect(order=1)
 */
class DemoAspect
{
    // ...
} 

@Aspect

Define a class as a facet class

  • Order priority, multiple aspects, the smaller the pre-execution

Declare entry point

A pointcut helps to determine the connection points (ie methods) of interest for different opinions.

 /**
 * Class DemoAspect
 *
 * @since 2.0
 *
 * @Aspect(order=1)
 *
 * @PointBean(
 *     include={"testOrderAop"}
 * )
 */
class DemoAspect
{
    // ...
} 

@PointBean

Define the bean pointcut. All public method executions in this bean class will pass the proxy of this aspect class.

  • Include defines the set of entity names that need to be cut in
  • Exclude defines the set of entity names to be excluded

Note that the entity name (class name) must specify the full path of the namespace such as 'App\Controller\HomeController' or use the use class to use the target class first.

Example: @PointBean(include={App\Controller\HomeController::class})

@PointAnnotation

Define 注解类 entry points, all methods that use the corresponding 注解 will pass the proxy of this aspect class

  • Include defines the set of 注解类名 that need to be cut in
  • Exclude defines the set of 注解类名 be excluded

Note that the entity name (class name) must specify the full path of the namespace such as 'App\Controller\HomeController' or use the use class to use the target class first.

Example: @PointAnnotation(include={Swoft\Http\Server\Annotation\Mapping\RequestMapping::class})

@PointExecution

Define matching pointcuts, indicating which methods to proxy the target class

  • Include defines the matching set to be cut in, the matching class method, and the regular expression
  • Exclude defines matching sets that need to be sorted, matching class methods, and supports regular expressions

Note that the entity name (class name) must specify the full path of the namespace such as 'App\Controller\HomeController' or use the use class to use the target class first.

Example: @PointExecution(include={"App\Http\Controller\AspectTestController::a.*"})

It should be noted here that if you need to use regular, the incoming code must be 双引号" " , and the double quotes must be the full path of the class.

The three defined relationships of @PointBean, @PointAnnotation, and @PointExecution are unions. The exclusion of the three definitions is also excluded after the union. It is recommended that for the sake of understanding and use, a facet class should try to use only one of the above three

Notice of notice

 use Swoft\Aop\Annotation\Mapping\After;
use Swoft\Aop\Annotation\Mapping\AfterReturning;
use Swoft\Aop\Annotation\Mapping\AfterThrowing;
use Swoft\Aop\Annotation\Mapping\Around;
use Swoft\Aop\Annotation\Mapping\Aspect;
use Swoft\Aop\Annotation\Mapping\Before;
use Swoft\Aop\Annotation\Mapping\PointBean;
use Swoft\Aop\Point\JoinPoint;
use Swoft\Aop\Point\ProceedingJoinPoint;

/**
 * Class DemoAspect
 *
 * @since 2.0
 *
 * @Aspect(order=1)
 *
 * @PointBean(
 *     include={"testOrderAop"}
 * )
 */
class DemoAspect
{
    /**
     * @Before()
     */
    public function before()
    {
        // before
    }

    /**
     * @After()
     */
    public function after()
    {
        // After
    }

    /**
     * @AfterReturning()
     *
     * @param JoinPoint $joinPoint
     *
     * @return mixed
     */
    public function afterReturn(JoinPoint $joinPoint)
    {
        $ret = $joinPoint->getReturn();

        // After return

        return $ret;
    }

    /**
     * @Around()
     *
     * @param ProceedingJoinPoint $proceedingJoinPoint
     *
     * @return mixed
     */
    public function around(ProceedingJoinPoint $proceedingJoinPoint)
    {
        // Before around
        $result = $proceedingJoinPoint->proceed();
        // After around

        return $result;
    }

    /**
     * @param \Throwable $throwable
     *
     * @AfterThrowing()
     */
    public function afterThrowing(\Throwable $throwable)
    {
        // afterThrowing
    }
} 
  • @Before pre-notification, execute this method before the target method is executed
  • @After post notification, execute this method after the target method is executed
  • @AfterReturning returns notifications
  • @AfterThrowing exception notification, this method is executed when the target method execution throws an exception
  • @Around surround notification, this method is executed before and after the target method is executed

AOP considerations

AOP only intercepts public and protected methods, and does not intercept private methods.

In addition, if there are multiple methods cut in the Sofft AOP, then another method that is cut in is called within one method, and the AOP will also weave the notification. For example, we define a class A which has two public methods fun1(),fun2() , and then we define a facet, using @PointBean(include={A::class}) annotate both methods in class A Cut in, this is the definition of the two methods we look at:

 <?php
class A
{
    function fun1()
    {
        echo 'fun1'."\n";
    }
    function fun2()
    {
        $this->fun1();
        echo 'fun2'."\n";
    }
} 

At this point, if we access the fun2() method, then our facets will be executed twice, and the execution order of the facets is the same as the execution order of the methods. The weaving notification of the fun2() method is executed first, and the weaving notification of the fun1() method is executed.

/docs/2.x/en/aop/statement.html
progress-bar