spring总结-----Spring AOP

What is AOP

aop (Aspect-Oriented Programming), i.e.,  aspect-oriented programming  , it OOP (Object-Oriented Programming, Object-Oriented Programming) complement each other, provided with OOP different perspective abstract software configuration. In OOP, we class (class) as our basic unit, the basic unit is AOP  Aspect (section)

the term

Aspect (section)

   aspect A  point cut and  advice composition, both comprising a transverse defined logic, the definition also includes connection points (join point) is. 

  Spring AOP is responsible for the implementation of the frame section, the logic will cross section defined woven into the designated section of the connection point. AOP is how to focus will enhance ( advice) woven into the upper connection point of the target object Target, where It consists of two tasks:

  1. How to locate a specific joinpoint by pointcut and advice

  2. Advice on how to write code section in.

Simply that the use of @Aspect annotated classes is cut, meet pointcut rules joinpoint add the appropriate advice will be operating.

advice (Enhanced)

Added to a particular aspect join point (i.e., satisfies rules join point point cut) piece of code. Many AOP frameworks, including the Spring AOP, advice will be modeled as an interceptor (Interceptor), and maintained on a plurality of join point advice, layer by layer to intercept.

Connection point (join point)

A point during program execution, such execution or exception processing methods. In Spring AOP, always indicates the point of attachment method execution.

Tangent point (point cut)

Predicate matching of the join point (a predicate that matches join points). Advice and is associated with a specific point cut, and performs the match point cut the join point.在 Spring 中, 所有的方法都可以认为是 joinpoint, 但是我们并不希望在所有的方法上都添加 Advice, 而 pointcut 的作用就是提供一组规则(使用 AspectJ pointcut expression language 来描述) 来匹配joinpoint, 给满足规则的 joinpoint 添加 Advice.

In Spring AOP, all the way to do is join point. The point cut is a description of the information, it is modified join point, via point cut, we can determine which join point can be woven into Advice. So join point and point cut on what is essentially two different latitudes.advice 是在 join point 上执行的, 而 point cut 规定了哪些 join point 可以执行哪些 advice

Audience (Target)

Weaving the target object's advice. Also called the target object  advised object.因为 Spring AOP 使用运行时代理的方式来实现 aspect, 因此 adviced object 总是一个代理对象(proxied object)注意, adviced object 指的不是原来的类, 而是织入 advice 后所产生的代理类.

Weaving (Weaving)

The process will aspect and other objects together and create adviced object according to different implementation technologies, AOP weaving in three ways:

  • Woven into the compiler, which requires a special Java compiler.

  • Weaving of class loading, which requires a special class loader.

  • Dynamic proxy weaving, adding a reinforcing (the Advice) in the target runtime class generation mode subclass. Weaving the Spring dynamic proxy, the compiler uses AspectJ weaving and weaving of class loading.

the type of advice

  • before advice, advice executed before the join point. Although before advice is to be executed before the join point, but it is not able to prevent the execution join point, unless an exception occurs (that is, before advice in our code, not artificially decide whether to continue to execute code in the join point)

  • after return advice, advice after a return to normal execution of the join point

  • after throwing advice, advice when a join point thrown executed

  • after (final) advice, whether it is a normal exit or join point occurs advice exception will be executed.

  • around advice, advice before and after the joint point join point exits are performed. This is the most common advice.

joinpoint Can be considered a  宾语rather  pointcut can be assimilated to modify  joinpoint the attribute, then the whole  aspect can be described as: 满足 pointcut 规则的 joinpoint 会被添加相应的 advice 操作.

introduction

Additional method or a field type. Spring AOP allows us to  目标对象 introduce new interfaces (and corresponding implementation). For example, we can use the introduction of a bean to achieve IsModified interfaces, and in order to simplify the implementation of caching.

AOP proxy

AOP woven into a class is the advice, it will produce a class result, which is a fusion of the original class and Enhanced Logic proxy class. In Spring AOP, AOP proxy is a proxy object or a CGLIB JDK dynamic proxy object.

Spring AOP defaults to using the standard JDK dynamic proxies (dynamic proxy) technology to achieve AOP proxy, through which we can be any interface agent. 如果需要为一个类实现代理, 那么可以使用 CGLIB 代理. When a business logic object does not implement the interface, then Spring AOP will default CGLIB as AOP agents. That is, if we need is a way to weave into the advice, but this method is not a method interfaces provided by the Spring AOP will use this time to implement dynamic proxy CGLIB. in view of this, Spring AOP recommendations are based on the interface programming, AOP interfaces rather than classes.

@AspectJ support

@AspectJ  is a coding style to achieve AOP using Java annotations. @AspectJ style AOP AspectJ Project 5 is introduced in AspectJ, Spring also supports @AspectJ and style of AOP

Use Java Configuration Mode Enable @AspectJ

@Configuration
@EnableAspectJAutoProxy
public class AppConfig {
}

Way to use XML to enable @AspectJ

<aop:aspectj-autoproxy/>

Defined aspect (section)

When using annotations  @Aspect  after tagging a Bean, the Spring framework will automatically collect Bean, and added to Spring AOP, such as:

@Component
@Aspect
public class MyTest {
}

Statement pointcut:

A pointcut declaration consists of two parts:

  • A method signature, including the method name and parameters

  • A pointcut expression that is used to specify which method is executed we are interested in (ie it can be woven into advice).

In @AspectJ style of AOP, we use a method to describe the pointcut, namely:

@Pointcut("execution(* com.xys.service.UserService.*(..))") // 切点表达式
private void dataAccessOperation() {} // 切点前面

这个方法必须无返回值.这个方法本身就是 pointcut signature, pointcut 表达式使用@Pointcut 注解指定.Above we simply define a pointcut, the pointcut described are: match all packets in com.xys.service.UserService  performed in all methods.

Statement pointcut

A pointcut declaration consists of two parts:

  • A method signature, including the method name and parameters

  • A pointcut expression that is used to specify which method is executed we are interested in (ie it can be woven into advice).

In @AspectJ style of AOP, we use a method to describe the pointcut, namely:

@Pointcut("execution(* com.xys.service.UserService.*(..))") // 切点表达式
private void dataAccessOperation() {} // 切点前面

这个方法必须无返回值.这个方法本身就是 pointcut signature, pointcut 表达式使用@Pointcut 注解指定.Above we simply define a pointcut, the pointcut described are: match all packets in com.xys.service.UserService  performed in all methods.

Cut point designator (designator the)

Cut point designator expression by AspectJ5 (designator the) and of operating parameters such as "Execution (  greetTo (..))" tangent point expression,  Execution  is the identifier, the number in parentheses  greetTo (..) is operating parameters

execution

Join point matching is performed, for example, "execution (* hello (..))" represents a matched hello () method for all object classes. This is the most basic pointcut identifier.

within

Match all join point at a particular package, for example,  within(com.xys.*) represents all the connection points com.xys package, i.e. all methods of all classes of the package while  within(com.xys.service.*Service) showing all Service classes all ending in com.xys.service package Junction.

this 与 target

Effect of this is to match a bean, which bean (Spring AOP proxy) is an example of a given type (instance of). The target matches with a target object (target Object, i.e. the need weaving advice original class), this object is an instance of a given type (instance of).

bean

All methods for the next match bean bean name specified value, for example:

bean(*Service) // 匹配名字后缀为 Service 的 bean 下的所有方法
bean(myService) // 匹配名字为 myService 的 bean 下的所有方法

args

The method of matching parameters required to meet. For example:

@Pointcut("within(com.xys.demo2.*)")
public void pointcut2() {
}

@Before(value = "pointcut2()  &&  args(name)")
public void doSomething(String name) {
    logger.info("---page: {}---", name);
}
@Service
public class NormalService {
    private Logger logger = LoggerFactory.getLogger(getClass());

    public void someMethod() {
        logger.info("---NormalService: someMethod invoked---");
    }


    public String test(String name) {
        logger.info("---NormalService: test invoked---");
        return "服务一切正常";
    }
}

When NormalService.test executed, the advice  doSomething will be executed, Test Method Parameter name is passed to  doSomething the.

Common examples:

// 匹配只有一个参数 name 的方法
@Before(value = "aspectMethod()  &&  args(name)")
public void doSomething(String name) {
}

// 匹配第一个参数为 name 的方法
@Before(value = "aspectMethod()  &&  args(name, ..)")
public void doSomething(String name) {
}

// 匹配第二个参数为 name 的方法
Before(value = "aspectMethod()  &&  args(*, name, ..)")
public void doSomething(String name) {
}

@annotation

The method specified by the matching annotations marked, for example:

@Pointcut("@annotation(com.xys.demo1.AuthChecker)")
public void pointcut() {
}

Annotation is matched by  AuthChecker the method marked.

Common expressions tangent point

Matching method signature

// 匹配指定包中的所有的方法
execution(* com.xys.service.*(..))

// 匹配当前包中的指定类的所有方法
execution(* UserService.*(..))

// 匹配指定包中的所有 public 方法
execution(public * com.xys.service.*(..))

// 匹配指定包中的所有 public 方法, 并且返回值是 int 类型的方法
execution(public int com.xys.service.*(..))

// 匹配指定包中的所有 public 方法, 并且第一个参数是 String, 返回值是 int 类型的方法
execution(public int com.xys.service.*(String name, ..))

Match type signature

// 匹配指定包中的所有的方法, 但不包括子包
within(com.xys.service.*)

// 匹配指定包中的所有的方法, 包括子包
within(com.xys.service..*)

// 匹配当前包中的指定类中的方法
within(UserService)


// 匹配一个接口的所有实现类中的实现的方法
within(UserDao+)

Bean name match

// 匹配以指定名字结尾的 Bean 中的所有方法
bean(*Service)

Cut point expression combination

// 匹配以 Service 或 ServiceImpl 结尾的 bean
bean(*Service || *ServiceImpl)

// 匹配名字以 Service 结尾, 并且在包 com.xys.service 中的 bean
bean(*Service) && within(com.xys.service.*)

Statement advice

advice and is associated with a pointcut expression, and will / run around before / after the join point matching method of execution.  pointcut 表达式可以是简单的一个 pointcut 名字的引用, 或者是完整的 pointcut 表达式. Here we have a few simple advice as an example, look at how to declare a advice of.

Before advice

/**
 * @author xiongyongshun
 * @version 1.0
 * @created 16/9/9 13:13
 */
@Component
@Aspect
public class BeforeAspectTest {
    // 定义一个 Pointcut, 使用 切点表达式函数 来描述对哪些 Join point 使用 advise.
    @Pointcut("execution(* com.xys.service.UserService.*(..))")
    public void dataAccessOperation() {
    }
}
@Component
@Aspect
public class AdviseDefine {
    // 定义 advise
    @Before("com.xys.aspect.PointcutDefine.dataAccessOperation()")
    public void doBeforeAccessCheck(JoinPoint joinPoint) {
        System.out.println("*****Before advise, method: " + joinPoint.getSignature().toShortString() + " *****");
    }
}

Here,  @Before  cited a pointcut, namely "com.xys.aspect.PointcutDefine.dataAccessOperation ()" is the name of a pointcut If we advice in the built pointcut, you can:

@Component
@Aspect
public class AdviseDefine {
    // 将 pointcut 和 advice 同时定义
    @Before("within(com.xys.service..*)")
    public void doAccessCheck(JoinPoint joinPoint) {
        System.out.println("*****doAccessCheck, Before advise, method: " + joinPoint.getSignature().toShortString() + " *****");
    }
}

around advice

around advice rather special, it can be added before a before and after different methods of operation, and can even decide when, how and whether the matching method to call.

@Component
@Aspect
public class AdviseDefine {
    // 定义 advise
    @Around("com.xys.aspect.PointcutDefine.dataAccessOperation()")
    public Object doAroundAccessCheck(ProceedingJoinPoint pjp) throws Throwable {
        StopWatch stopWatch = new StopWatch();
        stopWatch.start();
        // 开始
        Object retVal = pjp.proceed();
        stopWatch.stop();
        // 结束
        System.out.println("invoke method: " + pjp.getSignature().getName() + ", elapsed time: " + stopWatch.getTotalTimeMillis());
        return retVal;
    }
}

around advice and before advice in front of almost, but we have notes  @Before  changed to @Around  up.

 

 

 

Published 184 original articles · won praise 32 · views 110 000 +

Guess you like

Origin blog.csdn.net/wjandy0211/article/details/104005670