day42 sping aop_1 代理回顾

提到spring aop 我们先回顾一下java的代理,代理刚开始时用来实现代码的增强,主要有动态代理和静态代理。

一、静态代理

原理




看下面一个例子



如果用PersonDaoProxy 来代理PersonDao 不难发现,其虽然这个类的方法的代码功能增强,但是却是用重复代码来实现的。


总结结构:

   静态代理模式的缺点:

      1、如果一个系统中有100Dao,则创建100个代理对象

      2、如果一个dao中有很多方法需要事务,则代理对象的方法中重复代码还是很多

      3、由第一点和第二点可以得出:proxy的重用性不强


二、动态代理

spring 中的cglib代理和jdk提供的代理有很多共通之处,先回顾一下jdk的代理。从而了解aop概念。


动态代理模式:

   1、产生的代理对象和目标对象实现了共同的接口

       jdk动态代理

   2、代理对象是目标对象的子类

       hibernate: Person person =session.load(Person.class,1L); javassisit

       spring:cglib动态代理

jdk的动态代理:

   1、因为是用jdkAPI做到的

   2、代理对象是动态产生的

cglib产生的代理类是目标类的子类

注意事项:

    1、拦截器中invoke方法体的内容就是代理对象方法体的内容

    2、当客户端执行代理对象.方法时,进入到了拦截器的invoke方法体

    3 、拦截器中 invoke 方法的 method 参数是在调用的时候赋值的



代理类实现


package cn.zjy.proxyaop;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.util.List;

public class SalaryInterceptor implements InvocationHandler{

	
	private Object target;
	
	private List<Interceptor> interceptors;//这里把切面接口编程
	
	public SalaryInterceptor(Object target,List<Interceptor> interceptors){
		this.target = target;
		this.interceptors = interceptors;
	}
	
	public Object invoke(Object proxy, Method method, Object[] args)
			throws Throwable {
		
		System.out.print(interceptors.size());
		for(Interceptor interceptor:interceptors){
			interceptor.interceptor();
		}
		method.invoke(this.target, args);
		return null;
	}

}
客户端调用代理类

package cn.zjy.proxyaop;

import java.lang.reflect.Proxy;
import java.util.ArrayList;
import java.util.List;

import org.junit.Test;

public class SalaryTest {
	@Test
	public void test(){
		Object target = new SalaryManagerImpl();
		Logger logger = new Logger();
		Security security = new Security();
		Privilege privilege = new Privilege();
		List<Interceptor> interceptors = new ArrayList<Interceptor>();
		interceptors.add(logger);
		interceptors.add(security);
		interceptors.add(privilege);
		SalaryInterceptor interceptor = new SalaryInterceptor(target, interceptors);
		SalaryManager salaryManager = (SalaryManager)Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), interceptor);
		salaryManager.showSalary();
	}
}

结果

Logger
Security
privilege
查看工资

三、AOP的概念

看到上述动态代理,就可以做一个AOP名词的解释了

aop:

   1、切面

       事务、日志、安全性框架、权限等都是切面

   2、通知

      切面中的方法就是通知

   3、目标类

   4、切入点

        只有符合切入点,才能让通知和目标方法结合在一起

   5、织入:

         形成代理对象的方法的过程

接下来Spring 的cglib代理原理共通,不过代理类为目标类的子类实现

导入cglib jar包

之后,我们只需要修改代理类实现即可

package cn.zjy.proxyaop;

import java.lang.reflect.Method;
import java.util.List;

import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;

public class SalaryIntercept implements MethodInterceptor {

	
	private Object target;
	private List<Interceptor> interceptors;
	
	public SalaryIntercept(Object target,List<Interceptor> interceptors){
		this.target = target;
		this.interceptors = interceptors;
	}
	
	public Object createProxy()
	{
		Enhancer enhancer = new Enhancer();
		enhancer.setCallback(this);
		enhancer.setSuperclass(target.getClass());
		return enhancer.create();
	}
	
	public Object intercept(Object arg0, Method arg1, Object[] arg2,
			MethodProxy arg3) throws Throwable {
		for(Interceptor interceptor:interceptors){
			interceptor.interceptor();
		}
		arg1.invoke(this.target, arg2);
		return null;
	}

}
客户端验证

package cn.zjy.proxyaop;

import java.lang.reflect.Proxy;
import java.util.ArrayList;
import java.util.List;

import org.junit.Test;

public class SalaryTest {
	@Test
	public void test(){
		Object target = new SalaryManagerImpl();
		Logger logger = new Logger();
		Security security = new Security();
		Privilege privilege = new Privilege();
		List<Interceptor> interceptors = new ArrayList<Interceptor>();
		interceptors.add(logger);
		interceptors.add(security);
		interceptors.add(privilege);
//		SalaryInterceptor interceptor = new SalaryInterceptor(target, interceptors);
//		SalaryManager salaryManager = (SalaryManager)Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), interceptor);
//		salaryManager.showSalary();
		
		SalaryIntercept inter = new SalaryIntercept(target, interceptors);
		SalaryManager salaryManager	=(SalaryManager)inter.createProxy();
		salaryManager.showSalary();
		
	}
}

输出

Logger
Security
privilege
查看工资

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值