一.AOP介绍
- 面向切面编程;
- AOP采用横向抽取机制,取代传统纵向继承体系重复性代码;
- 作用:性能检测,事物管理,安全检查,缓存;
- Spring AOP使用纯Java实现,不需要专门的编译过程和类加载器,在运行期通过代理方式向目标类织入增强代码;
二.AOP相关概念
- Joinpoint(连接点):所谓连接点是指那些被拦截到的点,在spring中,这些点指的是方法,因为spring只支持方法类型的连接点;
- Pointcut(切入点):所为切入点是指我们要对那些Joinpoint进行拦截的定义;
- Advice(通知/增强):所谓通知是指拦截到Joinpoint之后所要做的事情就是通知,通知分为前置通知,后置通知,异常通知,最终通知,环绕通知(切面要完成的功能);
- Introduction(引介):引介是一种特殊的通知在不修改类的代码的前提下,Introduction可以运行为类动态地添加一些方法和属性(filed);
- Target(目标对象):代理的目标对象;
- Weaving(织入):是指把增强应用到目标对象来创建新的代理对象的过程,spring采用动态代理织入,而AspectJ采用编译器织入和类装载期织入;
- Proxy(代理):一个类被AOP织入增强后,就会产生一个结果类;
- Aspect(切面):是切入点和通知(引介)的结合
说明:
- 对于不使用接口的业务类,无法使用JDK代理类;
- CGLib采用非常底层字节码技术,可以为一个类创建子类,解决无接口代理问题.
三.code
- JDK
-
package com.batac.demo1; public interface UserDao { public void save(); public void update(); public void delete(); public void find(); }
package com.batac.demo1; public class UserDaoImpl implements UserDao { @Override public void save() { System.out.println("save"); } @Override public void update() { System.out.println("update"); } @Override public void delete() { System.out.println("delete"); } @Override public void find() { System.out.println("find"); } }
package com.batac.demo1; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; public class MyJdkProxy implements InvocationHandler { private UserDao userDao; public MyJdkProxy(UserDao userDao){ this.userDao = userDao; } public Object createProxy(){ Object object = Proxy.newProxyInstance(userDao.getClass().getClassLoader(),userDao.getClass().getInterfaces(),this); return object; } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { if ("save".equals(method.getName())){ System.out.println("增强save方法"); return method.invoke(userDao,args); } return method.invoke(userDao,args); } }
package com.batac.demo1; import org.junit.Test; public class UserDaoTest { @Test public void demo1(){ UserDao userDao = new UserDaoImpl(); UserDao proxy = (UserDao) new MyJdkProxy(userDao).createProxy(); proxy.save(); proxy.delete(); proxy.update(); proxy.find(); } }
- CGLIB
package com.batac.demo2;
public class ProductDao {
public void save(){
System.out.println("save");
}
public void delete(){
System.out.println("delete");
}
public void update(){
System.out.println("update");
}
public void find(){
System.out.println("find");
}
}
package com.batac.demo2;
import com.batac.demo1.MyJdkProxy;
import org.springframework.cglib.proxy.Enhancer;
import org.springframework.cglib.proxy.MethodInterceptor;
import org.springframework.cglib.proxy.MethodProxy;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
public class MyCglibProxy implements MethodInterceptor {
private ProductDao productDao;
public MyCglibProxy(ProductDao productDao){
this.productDao = productDao;
}
public Object createProxy(){
//1.创建核心类
Enhancer enhancer = new Enhancer();
//2.设置父类
enhancer.setSuperclass(productDao.getClass());
//3.设置回调
enhancer.setCallback(this);
//4.生成代理
Object proxy = (Object) enhancer.create();
return proxy;
}
@Override
public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
if ("save".equals(method.getName())){
System.out.println("加强save方法");
return methodProxy.invokeSuper(o,objects);
}
return methodProxy.invokeSuper(o,objects);
}
}
package com.batac.demo2;
import org.junit.Test;
public class ProductDaoTest {
@Test
public void demo1(){
ProductDao productDao = new ProductDao();
ProductDao productDao1 = (ProductDao) new MyCglibProxy(productDao).createProxy();
productDao1.save();
productDao1.delete();
productDao1.find();
productDao1.update();
}
}
导入依赖
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
<version>5.1.9.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.1.9.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-expression</artifactId>
<version>5.1.9.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>5.1.9.RELEASE</version>
</dependency>
总结
版权声明:本文为Batac_Lee原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。