AOP Overview
- Simple it is to repeat our program code extracted, when you need to perform, using dynamic proxy technology, without modifying the source code, based on our existing methods enhanced.
- AOP role and advantages
- Role:
During the program run, does not modify the source code to the existing enhanced method. - Advantages:
reduce duplication of code
to improve development efficiency
and easy maintenance
- Role:
Dynamic agent commonly used in two ways
- Dynamic agent interface
provider: JDK official Proxy class.
Requirements: The minimum proxy class that implements an interface. - Dynamic Proxy subclass
provider: third party CGLib, if reported asmxxxx abnormal, you need to import asm.jar.
Requirements: agent class can not be modified with the final class (final class).
Create a proxy object using the Enhancer class CGLib
/**
* 一个演员
*/
public class Actor{//没有实现任何接口
public void basicAct(float money){
System.out.println("拿到钱,开始基本的表演:"+money);
}
public void dangerAct(float money){
System.out.println("拿到钱,开始危险的表演:"+money);
}
}
public class Client {
/**
* 基于子类的动态代理
* 要求:
* 被代理对象不能是最终类
* 用到的类:
* Enhancer
* 用到的方法:
* create(Class, Callback)
* 方法的参数:
* Class:被代理对象的字节码
* Callback:如何代理
* @param args
*/
public static void main(String[] args) {
final Actor actor = new Actor();
Actor cglibActor = (Actor) Enhancer.create(actor.getClass(),
new MethodInterceptor() {
/**
* 执行被代理对象的任何方法,都会经过该方法。在此方法内部就可以对被代理对象的任何
方法进行增强。
*
* 参数:
* 前三个和基于接口的动态代理是一样的。
* MethodProxy:当前执行方法的代理对象。
* 返回值:
* 当前执行方法的返回值
*/
@Override
public Object intercept(Object proxy, Method method, Object[] args,
MethodProxy methodProxy) throws Throwable {
String name = method.getName();
Float money = (Float) args[0];
Object rtValue = null;
if("basicAct".equals(name)){
//基本演出
if(money > 2000){
rtValue = method.invoke(actor, money/2);
}
}
if("dangerAct".equals(name)){
//危险演出
if(money > 5000){
rtValue = method.invoke(actor, money/2);
}
}
return rtValue;
}
});
cglibActor.basicAct(10000);
cglibActor.dangerAct(100000);
}
}
In Spring AOP
AOP related terms
- JoinPoint (connection points):
a so-called connection points are those points being intercepted. In the spring, these points refers to a method, because only the spring type connection point supporting method.
- Pointcut (entry point):
The so-called entry points means we have to define the intercept which Joinpoint.
- Advice (notification / Enhanced):
The so-called notice refers to Joinpoint after intercepting the thing to do is to inform.
Type of notification: notification front, rear notification, abnormality notification, the final notification, around advice.
- Introduction (introducing):
introducing a notification is a special class code without modifying the premise, Introduction class may be dynamically added or Field methods at runtime.
- Target (Audience):
proxy target object.
- Weaving (weaving):
it refers to the enhancement applied to the target object to the process of creating a new proxy object.
Agent dynamic spring weaving, while the weaving AspectJ using compile and class loading of weaving.
- The Proxy (Agent):
after being woven into a class enhanced AOP, to produce a result proxy class.
- Aspect (section):
is a combination of pointcuts and (introduce) a.
AOP XML-based configuration
- The first step: Import coordinate spring
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.2.4.RELEASE</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.8.7</version>
</dependency>
</dependencies>
- Do not forget to import dependence aspectJ aop dependencies
- Step 2: Create spring configuration file and import constraints
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd">
</beans>
- Step Three: Configure the spring ioc
<bean id="UserService" class="cn.myp666.service.impl.UserServiceImpl"></bean>
<bean id="UserLog" class="cn.myp666.service.UserLog"></bean>
<!--
<aop:config>
<aop:pointcut id="lg1" expression="execution( public void cn.myp666.service.impl.UserServiceImpl.saveUser())"/>
<aop:aspect id="logAdvice" ref="UserLog">
<aop:before method="printLog" pointcut-ref="lg1"></aop:before>
</aop:aspect>
</aop:config>
-->
<aop:config>
<aop:aspect id="logAdvice" ref="UserLog">
<aop:before method="printLog" pointcut="execution( public void cn.myp666.service.impl.UserServiceImpl.saveUser())"></aop:before>
</aop:aspect>
</aop:config>
- aop: config:
Role: used to configure the aop declaration beginning
<aop: config>
<-! configuration code is written here ->
</ aop: config>
- aop: aspect:
action:
a configuration section.
Properties:
the above mentioned id: section to provide a unique identification.
ref: reference id configured notification class bean.
- aop: pointcut:
Role:
used to configure the entry point expression. Which method is to specify which enhanced the class right.
Properties:
expression The: expression used to define the starting point.
id: entry point for expression to provide a unique identification
<aop:pointcut id="lg1" expression="execution( public void cn.myp666.service.impl.UserServiceImpl.saveUser())"/>
<aop:aspect id="logAdvice" ref="UserLog">
<aop:before method="printLog" pointcut-ref="lg1"></aop:before>
</aop:aspect>
- aop: before
action:
a pre-configured notification. Enhanced specified entry point method is performed before
attributes:
Method: name specifies the notification method for enhancing class
ponitcut-ref: reference to a specific starting point for the expression of
poinitcut: for expression pointcuts
- aop: after-returning
effect:
for configuring post-notification
properties:
Method: Specifies the name of the notification process.
pointct: define a pointcut expression
pointcut-ref: Specifies the entry point of reference expression
- aop: after-throwing
action:
to configure abnormality notification
attribute:
Specifies the name of the notification method: method.
pointct: define a pointcut expression
pointcut-ref: Specifies the entry point of reference expression
- aop: after
effect:
for configuring notifications final
properties:
Method: Specifies the name of the notification process.
pointct: define a pointcut expression
pointcut-ref: Specifies the entry point of reference expression
-
execution: perform (conventional) matching method
- execution (expression)
-
Expression syntax:
execution([修饰符] 返回值类型 包名.类名.方法名(参数))
-
Written instructions:
- public void cn.myp666.service.impl.UserServiceImpl.saveUser()
- Full wildcard ways:
* *..*.*(..)
-
Under normal circumstances, we are all on the method of enhanced business layer, so the starting point expressions are cut into the business layer implementation class.
execution(* cn.myp666.service.impl.*.*(..))