SpringAOP
springAOP实现方式
1.动态代理 使用 Proxy机制,使用反射技术,创建实际对象的代理对象,添加AOP的逻辑后执行。
2.动态字节码增强 ASM CGLIB的工具库实现
AOP概念
1.joinpoint 目标对象上的要执行AOP的具体执行点。和pointcut类似于对象实例和类的概念,pointcut规定一组判断逻辑,符合多级的具体点就是一个个的joinpoint,而pointcut规定的表达式指定的则是一组joinpoint。
2.pointcut 需要执行AOP切入的一个切入点,这个点是所有符合该cut定义的位置的集合(expression="execution()")
3.advice AOP的增强逻辑代码,针对一个point指定的方法定义的要做的逻辑操作。advice可以是方法前、后、异常、环绕等概念
advice根据不同的执行顺序定义为before,afterreturning,afterthrowing,after,around,以及interceptor等不同的advise。
4.aspect 关联advice和pointcut的概念实体,通过aspect的定义,可以组合advice到pointcut中。
5.weaver 织入器,把aop的advice插入到目标对象的横切点中去的具体实现。
AOP概念 pointcut的局部分支图 image.png
image.png
image.png image.png
动态代理
spring 动态代理机制使用 Proxy和InvocationHandler两个reflect包中的对象来实现运行时的动态代理机制。
package com.lwf.jms;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
public class test {
public static void main(String[] args) {
Itest test=(Itest) Proxy.newProxyInstance(test.class.getClassLoader(), new Class[]{Itest.class}, new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("invocationHandler is ok");
// method.invoke(proxy,args);
System.out.println(proxy.getClass());
System.out.println("method is over");
return null;
}
});
test.talk();
System.out.println(test.getClass());
}
interface Itest{
void talk();
}
}
spring集成并实现了cglib的字节码增强技术,主要通过enhancer 和callback的方法实现,一般情况下,callback都使用其子接口MethodInterceptor
enhancer增强的类不能是内部类,内部类会默认读取到其外部类,从而出现错误。
package com.lwf.jms;
import org.springframework.cglib.proxy.Enhancer;
import org.springframework.cglib.proxy.MethodInterceptor;
import org.springframework.cglib.proxy.MethodProxy;
import java.lang.reflect.Method;
public class enhancertest {
public static void main(String[] args) {
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(Talker.class);
enhancer.setCallback(new MethodInterceptor() {
@Override
public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
System.out.println("enhancer is starting");
System.out.println("method name :" + method.getName());
methodProxy.invokeSuper(o, objects);
System.out.println("enhancer is over");
return null;
}
});
Talker talker = (Talker) enhancer.create();
talker.talk();
talker.speak();
}
}
public class Talker {
public void talk() {
System.out.println("talker is talking");
}
public void speak() {
System.out.println("talker is speaking");
}
}
springAOP的代理实现
springAOP中通过spring的动态代理机制实现AOP的植入,基础类为org.springframework.aop.framework.ProxyFactory,proxyfactory通过通过继承和扩展实现advicedSupport,通过组合内部拥有了一个AopProxyFactory的field(a opproxyfactory可以createproxy从而创建出proxy),集AopProxy和AdvicedSupport功能于一身,通过设置advisor来拥有AOP的定义,通过proxy功能来把aop功能植入到proxy代理对象中,实现功能!
image.png
image.png
package com.lwf.jms;
import org.springframework.aop.framework.ProxyFactory;
import org.springframework.aop.support.NameMatchMethodPointcutAdvisor;
public class ProxyFactoryTest {
public static void main(String[] args) {
ProxyFactory proxyFactory = new ProxyFactory(new Talker());
// proxyFactory.setOptimize(true);
// proxyFactory.setProxyTargetClass(true);
NameMatchMethodPointcutAdvisor nameMatchMethodPointcutAdvisor = new NameMatchMethodPointcutAdvisor();
nameMatchMethodPointcutAdvisor.setMappedName("talk");
nameMatchMethodPointcutAdvisor.setAdvice(new methodInterceptor());
proxyFactory.addAdvisor(nameMatchMethodPointcutAdvisor);
Talker proxy = (Talker) proxyFactory.getProxy();
// proxy.speak();
proxy.talk();
System.out.println(proxy.getClass());
}
}
package com.lwf.jms;
import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
public class methodInterceptor implements MethodInterceptor {
@Override
public Object invoke(MethodInvocation invocation) throws Throwable {
System.out.println("method name :"+invocation.getMethod().getName());
Object rtn =invocation.proceed();
System.out.println("invoke is over");
return rtn;
}
}
CGLIB执行结果
proxy执行结果
methoeinterceptor类使用的是org.aopalliance.intercept.MethodInterceptor,在CGLIB中
image.png
springAOP的自动代理机制
proxyfactorybean实现了spring的aop植入,那么spring如何实现自动化织入?spring借助applicationcontext的Ioc容器,通过BeanPostProcessor的Ioc初始化拦截进行操作。通过ioc容器的bean的初始化时添加一个给aop功能使用的BeanPostProcessor,在遍历初始化bean时实现autoproxy,生成代理对象。
- 具体实现类
spring在org.springframework.aop.framework.autoproxy包中提供了AutoProxyCreator类来实现自动代理功能
autoproxycreator的结构图
注解形式的AOP
基于注解形式的aop是spring集成了aspectj中的注解,并利用aspectj中的注解相关的pointcut表达式进行pointcut解析,利用自动代理功能实现注解模式下的aop功能
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.9.4</version>
<scope>compile</scope>
</dependency>
@aspect,@pointcut注解
- pointcut表达式
- execution()
- within(@aspect class)
- this 、target
@before @after @around 实现advice逻辑功能