众所周知spring的核心是 ioc 和aop
这一篇文章我们主要介绍spring框架中是如何实现AOP的。
AOP是什么?
AOP即面向切面编程思想,这是一种编程思想,和语言无关。可以用八个字来概括:横向重复纵向抽取。比如我们用filter来 解决servlet的乱码问题就应用了AOP思想,动态代理也应用了AOP思想。下面的两张图可以帮助我们理解AOP思想。
spring中也实现了AOP思想。
spring中用了动态代理技术和cglib代理技术实现AOP
以动态代理为主,cglib代理为辅。
动态代理要求目标对象必须实现接口,否则不能代理,而cglib代理就是继承目标对象实现代理,所以可以给任何目标对象代 理。
在spring中当目标对象实现了接口的时候就会使用动态代理,当要增强的类没有实现接口的时候 就使用cglib代理。
下面的代码演示如何使用动态代理获得代理对象。
这是要增强的接口
/*
* 用户service
* 也就是要增强的类
*/
public interface UserService {
//添加
public void save();
//删除
public void delete();
//修改
public void update();
//查找
public void find();
}
这是要增强的类
/*
* 实现了UserService接口的类
*/
public class UserServiceImpl implements UserService{
@Override
public void save() {
System.out.println("添加用户");
//int i=10/0;
}
@Override
public void delete() {
System.out.println("删除用户");
}
@Override
public void update() {
System.out.println("修改用户");
}
@Override
public void find() {
System.out.println("查找用户");
}
}
这是获得代理对象的工厂
/*
* 动态代理对象工厂
*/
public class ProxyFactory{
private Object targetObject;//目标对象
public ProxyFactory(Object target) {
this.targetObject=target;
}
/*
* 得到代理对象
*/
public Object createProxy() {
/*
* 准备类加载器,实现的接口的Class对象,InvocationHandler对象三大参数
*
*/
ClassLoader loader=targetObject.getClass().getClassLoader();
Class[] cs=targetObject.getClass().getInterfaces();
InvocationHandler h=new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("开启事务");
Object o=method.invoke(targetObject, args);
System.out.println("关闭事务");
return o;
}
};
Object o=Proxy.newProxyInstance(loader, cs, h);//获得代理对象
return o;//返回代理对象
}
}
测试方法
public void fun() {
ProxyFactory factory=new ProxyFactory(new UserServiceImpl());
UserService usProxy=(UserService) factory.createProxy();
usProxy.save();
//判断代理对象是否属于被代理对象的类型
//代理对象继承了被代理对象=false
System.out.println(usProxy instanceof UserServiceImpl);
}
结果
下面的代码演示如何使用cglib代理获得代理对象(要增强的类和动态代理增强的类一样,只是代理工厂不一样)
/*
* cglib代理工厂类
*/
public class EnhancerFactory {
private Object targetObject;
public EnhancerFactory(Object targetObject) {
this.targetObject=targetObject;
}
public Object createEnhancer() {
Enhancer en=new Enhancer();//帮我们生成代理对象
en.setSuperclass(targetObject.getClass());//设置对谁进行代理
MethodInterceptor call=new MethodInterceptor() {
@Override
public Object intercept(Object object, Method arg1, Object[] param, MethodProxy methodProxy) throws Throwable {
//打开事务
System.out.println("打开事务");
//执行原有方法
Object o=methodProxy.invokeSuper(object, param);
//提交事务
System.out.println("提交事务");
return o;
}
};
en.setCallback(call);//代理要做什么
Object o=en.create();//创建代理
return o;
}
}
测试方法
public void fun1() {
EnhancerFactory factory=new EnhancerFactory(new UserServiceImpl());
UserService userService= (UserService) factory.createEnhancer();
userService.save();
//判断代理对象是否属于被代理对象的类型
//代理对象继承了被代理对象=true
System.out.println(userService instanceof UserServiceImpl);
}
结果
这就是spring 实现AOP的原理。