cglib动态代理例子和浅剖Spring Aop机制

1.cglib动态代理例子

  要导入cglib的jar包


package com.arvon.cglibproxydemo;

/**
 * 目标类
 *@author Huangwen
 *2017-3-30
 */
public class Target {
	public void mainLogicMethod(){
		System.out.println("Target.mainLogicMethod()");
	}
	
}
//----------------------------------------------------------------

package com.arvon.cglibproxydemo;
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;
/**
 * 目标类的拦截器
 *@author Huangwen
 *2017-3-30
 */
public class TargetInterceptor implements MethodInterceptor{
	private Target target;
	private List<Interceptor> interceptors;
	public TargetInterceptor(Target target, List<Interceptor> interceptors) {
		this.target = target;
		this.interceptors = interceptors;
	}
	/**
	 * 产生代理对象
	 * @return
	 */
	public Object createProxy(){
		Enhancer enhancer = new Enhancer();
		enhancer.setCallback(this); 
		enhancer.setSuperclass(this.target.getClass());//设置产生的代理对象的父类 
		return enhancer.create();
	}
	@Override
	public Object intercept(Object arg0, Method menthod, Object[] arg2,
			MethodProxy arg3) throws Throwable {
		//所有的拦截器执行拦截方法
		for (Interceptor interceptor : interceptors) {
			interceptor.interceptor();
		}
		menthod.invoke(target, arg2);
		return null;
	}
}







package com.arvon.cglibproxydemo;
/**
 * 拦截器接口
 *@author Huangwen
 *2017-3-30
 */
public interface Interceptor {
	/**
	 * 拦截方法
	 */
	public void interceptor();
}


/**
 * 模拟安全性框架
 *@author Huangwen
 *2017-3-30
 */
public class Security implements Interceptor {
	@Override
	public void interceptor() {
		System.out.println(">>>>>do something about security");
	}
}


/**
 * 模拟日志类框架
 *@author Huangwen
 *2017-3-30
 */
public class Logger implements Interceptor {
	@Override
	public void interceptor() {
		System.out.println(">>>>>do something about logging");
	}
}


package com.arvon.cglibproxydemo;
import java.util.ArrayList;
import java.util.List;
/**
 * 测试类
 *@author Huangwen
 *2017-3-30
 */
public class Client {
	public static void main(String[] args) {
		Target target= new Target();
		Logger logger = new Logger();
		Security  security = new Security();
		List<Interceptor> interceptors = new ArrayList<Interceptor>();
		interceptors.add(security);
		interceptors.add(logger);
		TargetInterceptor targetInterceptor = new TargetInterceptor(target, interceptors);
		Target Proxy = (Target)targetInterceptor.createProxy();
		Proxy.mainLogicMethod();
	}
}



输出

>>>>>do something about security
>>>>>do something about logging
Target.mainLogicMethod()





--------------------------------------------------

浅剖Spring Aop机制


jdk的动态代理:
   1、因为是用jdk的API做到的
   2、代理对象是动态产生的
cglib产生的代理类是目标类的子类

注意事项:
    1、拦截器中invoke方法体的内容就是代理对象方法体的内容
    2、当客户端执行代理对象.方法时,进入到了拦截器的invoke方法体

aop的一些概念:
   1、切面
        事务、日志、安全性框架、权限等都是切面
   2、通知
      切面中的方法就是通知
   3、目标类
   4、切入点
         只有符合切入点,才能让通知和目标方法结合在一起
   5、织入:
         形成代理对象的方法的过程
          
 
好处:
   事务、日志、安全性框架、权限、目标方法之间完全是松耦合的


切入点表达式


    
   execution(public * *(..))  所有的公共方法

   execution(* set*(..))  以set开头的任意方法

   execution(* com.xyz.service.AccountService.*(..)) com.xyz.service.AccountService类中的所有的方法

   execution(* com.xyz.service.*.*(..))  com.xyz.service包中的所有的类的所有的方法

   execution(* com.xyz.service..*.*(..)) com.xyz.service包及子包中所有的类的所有的方法

   execution(* cn.itcast.spring.sh..*.*(String,?,Integer))  cn.itcast.spring.sh包及子包中所有的类的有三个参数
                                                            第一个参数为String,第二个参数为任意类型,
                                                            第三个参数为Integer类型的方法


    
springAOP的具体加载步骤:
   1、当spring容器启动的时候,加载了spring的配置文件
   2、为配置文件中所有的bean创建对象
   3、spring容器会解析aop:config的配置
       1、解析切入点表达式,用切入点表达式和纳入spring容器中的bean做匹配
            如果匹配成功,则会为该bean创建代理对象,代理对象的方法=目标方法+通知
            如果匹配不成功,不会创建代理对象
   4、在客户端利用context.getBean获取对象时,如果该对象有代理对象则返回代理对象,如果代理对象,则返回目标对象

说明:如果目标类没有实现接口,则spring容器会采用cglib的方式产生代理对象,如果实现了接口,会采用jdk的方式


通知
   1、前置通知
      1、在目标方法执行之前执行
      2、无论目标方法是否抛出异常,都执行,因为在执行前置通知的时候,目标方法还没有执行,还没有遇到异常
   2、后置通知
      1、在目标方法执行之后执行
      2、当目标方法遇到异常,后置通知将不再执行
      3、后置通知可以接受目标方法的返回值,但是必须注意:
               后置通知的参数的名称和配置文件中returning="var"的值是一致的
   3、最终通知:
      1、在目标方法执行之后执行
      2、无论目标方法是否抛出异常,都执行,因为相当于finally
   4、异常通知
      1、接受目标方法抛出的异常信息
      2、步骤
           在异常通知方法中有一个参数Throwable  ex
           在配置文件中
              <aop:after-throwing method="throwingMethod" pointcut-ref="perform" throwing="ex"/>
   5、环绕通知
       1、如果不在环绕通知中调用ProceedingJoinPoint的proceed,目标方法不会执行
       2、环绕通知可以控制目标方法的执行






评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值