AOP是Spring两大特性之一,他的意思为面向切面编程。使用AOP可以抽取一些公共模块出来,减少公共模块和业务代码的耦合。利用 AOP 可以对业务逻辑的各个部分进行隔离,从而使得业务逻辑各 部分之间的耦合度降低,提高程序的可重用性,同时提高了开发的效率。 AOP、OOP 在字面上虽然非常类似,但却是面向不同领域的两种设计思想。OOP (面向对象编程)
针对业务处理过程的实体及其属性和行为进行抽象封装,以获 得更加清晰高效的逻辑单元划分。
类中可以被增强的方法,这个方法就被称为连接点
类中有很多方法可以被增强,但实际中只有 add 和 update被增了,那么 add 和 update 方法就被称为切入点(实际实现的连接点)
通知是指一个切面在特定的连接点要做的事情(增强的功能)。通知分为方法执行前通知,方法执行后通知,环绕通知、异常通知和返回通知等.
把通知添加到切入点的过程叫切面.
代理的目标对象(要增强的类)
向目标对象应用通知之后创建的代理对象
具体实现方式翻阅之前写的博客
AOP和事务管理
SpringAOP是通过代理来实现面向切面编程的,它使用的代理有两种,JDK代理和CGlib代理
。当我们的bean对象实现了某一接口后,Spring默认将采用Jdk动态代理,当我们的bean对象没有实现接口时,默认将采用CGLIB代理,Spring也支持我们在bean对象实现了接口时也强制的使用CGLIB代理。
JDK动态代理基于拦截器和反射来实现。代理类必须要实现InvocationHandler
接口,重写invoke()
方法。
代码实现:
接口类:UserDao
//抽象用户操作定义
public interface UserDao {
void saveUser();
}
两个实现类,普通用户实现UserDaoImpl
和VIP用户实现VipUserDaoImpl
public class UserDaoImpl implements UserDao{
@Override
public void saveUser() {
System.out.println("普通用户实现");
//增加新功能要在每个实现类里面写
//saveLog()
}
}
public class VipUserDaoImpl implements UserDao{
@Override
public void saveUser() {
System.out.println("VIP用户实现");
//增加新功能要在每个实现类里面写
//saveLog()
}
}
动态代理类Dtproxy
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
//实现java.lang包下的reflect类的InvocationHandler接口
public class Dtproxy implements InvocationHandler {
Object object;//真实对象
public Dtproxy(Object object){
this.object = object;
}
/*
invoke() 反射
Method method 动态获取的真正的要执行的saveUser()方法,用反射的机制获取到
*/
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("之前开始事务");
method.invoke(object);
System.out.println("之后提交事务");
return proxy;
}
/**
* 动态代理类
* 代理类不需要实现与目标类相同的接口,这样就可以代理任意的目标类
* 但是有要求,目标类必须实现接口,此种方式是动态代理的实现方式之一,成为JDK代理。
* jdk代理:是一种纯反射机制实现的(动态获取目标接口的方法)
*/
}
测试类Test
:
public class Test {
public static void main(String[] args) {
VipUserDaoImpl vipUserDao = new VipUserDaoImpl();
InvocationHandler dtproxy = new Dtproxy(vipUserDao);
//创建代理对象
UserDao userDao = (UserDao)Proxy.newProxyInstance(Dtproxy.class.getClassLoader(),VipUserDaoImpl.class.getInterfaces(),dtproxy);
userDao.saveUser();
}
}
JDK代理是通过反射来实现,JDK通过反射,生成一个代理类,这个代理类实现了原来那个类的所有接口,并对接口定义的方法进行代理。当我们通过代理对象执行原来那个类的方法时,代理类底层会通过反射机制,回调我们实现的InvocationHandler接口的invoke方法。
优点:
缺点:
CGLIB实现动态代理的原理是:底层采用ASM字节码生成框架,直接对需要代理的类的字节码进行操作,生成这个类的一个子类,并且重写类的所有方法。
优点:
缺点