“Spring:AOP”的版本间差异
跳到导航
跳到搜索
(→AOP 实现) |
|||
第10行: | 第10行: | ||
== AOP 实现 == | == AOP 实现 == | ||
Spring 的AOP 的底层用到两种代理机制: | Spring 的AOP 的底层用到两种代理机制: | ||
* '''JDK 动态代理''' | * '''JDK 动态代理''':(实现了接口)使用动态代理创建'''接口实现类代理对象'''; | ||
* '''CGLIB 动态代理''' | * '''CGLIB 动态代理''':(没有实现接口)使用动态代理创建'''类的子类代理对象''';(在子类中调用父类的方法,来完成增强) | ||
** 应用的是底层的字节码增强的技术生成当前类的子类对象; | ** 应用的是底层的字节码增强的技术生成当前类的子类对象; | ||
=== JDK 动态代理 === | === JDK 动态代理 === | ||
* 参见:'''[http://wiki.eijux.com/%E6%A0%B8%E5%BF%83%E6%8A%80%E6%9C%AF%EF%BC%9A%E6%8E%A5%E5%8F%A3%E3%80%81lambda%E8%A1%A8%E8%BE%BE%E5%BC%8F%E4%B8%8E%E5%86%85%E9%83%A8%E7%B1%BB#.E4.BB.A3.E7.90.86 JavaCore:接口(代理)]'''中的代理部分; | |||
<syntaxhighlight lang="java"> | <syntaxhighlight lang="java"> | ||
public class MyJDKProxy implements InvocationHandler { | public class MyJDKProxy implements InvocationHandler { | ||
第41行: | 第41行: | ||
=== CGLIB 动态代理 === | === CGLIB 动态代理 === | ||
* 参见:[http://wiki.eijux.com/%E5%8A%A8%E6%80%81%E4%BB%A3%E7%90%86%E3%80%81CGLIB_%E4%B8%8E_%E5%88%87%E9%9D%A2%E7%BC%96%E7%A8%8B#CGLIB “动态代理、CGLIB 与 切面编程”(CGLIB)] | |||
<syntaxhighlight lang="java"> | <syntaxhighlight lang="java"> | ||
public class MyCglibProxy implements MethodInterceptor { | public class MyCglibProxy implements MethodInterceptor { |
2020年10月29日 (四) 01:05的版本
关于AOP
Aspect Oriented Programming:面向切面编程,通过预编译方式和运行期间动态代理实现程序功能的统一维护的。
- AOP是OOP的延续。
- 可以在不修改源码的情况下,对程序进行增强;
- 应用如:权限校验,日志记录,性能监控,事务控制;
AOP 实现
Spring 的AOP 的底层用到两种代理机制:
- JDK 动态代理:(实现了接口)使用动态代理创建接口实现类代理对象;
- CGLIB 动态代理:(没有实现接口)使用动态代理创建类的子类代理对象;(在子类中调用父类的方法,来完成增强)
- 应用的是底层的字节码增强的技术生成当前类的子类对象;
JDK 动态代理
- 参见:JavaCore:接口(代理)中的代理部分;
public class MyJDKProxy implements InvocationHandler {
private UserDao userDao;
public MyJDKProxy(UserDao userDao) {
this.userDao = userDao;
}
// 编写工具方法:生成代理:
public UserDao createProxy() {
UserDao userDaoProxy = (UserDao)Proxy.newProxyInstance(userDao.getClass().getClassLoader(),
userDao.getClass().getInterfaces(), this);
return userDaoProxy;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
if("save".equals(method.getName())) {
System.out.println("权限校验================");
}
return method.invoke(userDao, args);
}
}
CGLIB 动态代理
public class MyCglibProxy implements MethodInterceptor {
private CustomerDao customerDao;
public MyCglibProxy(CustomerDao customerDao) {
this.customerDao = customerDao;
}
// 生成代理的方法:
public CustomerDao createProxy() {
// 创建Cglib 的核心类:
Enhancer enhancer = new Enhancer();
// 设置父类:
enhancer.setSuperclass(CustomerDao.class);
// 设置回调:
enhancer.setCallback(this);
// 生成代理:
CustomerDao customerDaoProxy = (CustomerDao) enhancer.create();
return customerDaoProxy;
}
@Override
public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
if("delete".equals(method.getName())) {
Object obj = methodProxy.invokeSuper(proxy, args);
System.out.println("日志记录================");
return obj;
}
return methodProxy.invokeSuper(proxy, args);
}
}
基于AspectJ的AOP
相关术语
- Joinpoint(连接点):所谓连接点是指那些被拦截到的点。【可以被切入的方法】
- 在spring 中,这些点指的是方法,因为spring 只支持方法类型的连接点;
- Pointcut(切入点):所谓切入点是指我们要对哪些Joinpoint 进行拦截的定义;【用来切入的方法】
- Advice(通知/增强):所谓通知是指拦截到Joinpoint 之后所要做的事情就是通知;【切面处理】
- 通知分为“前置通知”,“后置通知”,“异常通知”,“最终通知”,“环绕通知”(切面要完成的功能)
- Introduction(引介):引介是一种特殊的通知在不修改类代码的前提下, Introduction可以在运行期为类动态地添加一些方法或Field;
- Target(目标对象):代理的目标对象;
- Weaving(织入):是指把增强应用到目标对象来创建新的代理对象的过程;【应用增强生成代理对象】
- spring采用“动态代理织入”,而AspectJ采用“编译期织入”和“类装载期织入”;【?】
- Proxy(代理):一个类被AOP 织入增强后,就产生一个结果代理类;
- Aspect(切面): 是切入点和通知(引介)的结合;
jar包
- spring 的传统AOP 的开发的包:
- “spring-aop-4.2.4.RELEASE.jar”
- “com.springsource.org.aopalliance-1.0.0.jar”
- aspectJ 的开发包:
- “com.springsource.org.aspectj.weaver-1.6.8.RELEASE.jar”
- “spring-aspects-4.2.4.RELEASE.jar”
配置文件
需要在“applicationContext.xml”中引入AOP相关约束:
<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>