spring底层如何实现AOP(动态代理和cglib代理如何实现代理)

众所周知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的原理。

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值