spring学习笔记6--简单模拟实现AOP(cglib版)

前言:最近在复习spring特记录于此,欢迎大家交流指正---QQ:767872620

 

本小例子使用cglib实现动态代理类

cglib-nodep-2.2.2.jar下载地址:

 http://download.csdn.net/detail/hollboy/5327795

 

代码如下:

目标类:(目标类(业务类)没有实现任何接口时使用cglib-nodep-2.2.2.jar实现AOP

package cn.itcast.service.imp;

import cn.itcast.service.PersonService;
/**
 * 
 * @author Mars
 *1.拦截所有业务方法
 *2。判断用户是否有权限,有权限就允许他执行业务方法,没有权限就不允许他执行业务方法
 *是否有权限是根据user是否为null作为判断依据
 *3.通过cglib-nodep-2.2.2.jar实现AOP
 */
public class PersonServiceBean2  {

	public PersonServiceBean2(String user) {
		super();
		this.user = user;
	}
	public String getUser() {
		return user;
	}


	public String user = null;
	public PersonServiceBean2(){
		
	}
	public String getPersonName(Integer personid) {
		return "xxx";
	}


	public void save(String name) {
		System.out.println("我是save方法");
	}


	public void update(String name, Integer personid) {
		System.out.println("我是update方法");
	}

}

代理类:

package cn.itcast.aop;

import java.lang.reflect.Method;

import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;
import cn.itcast.service.imp.PersonServiceBean2;
/**
 * 目标对象(业务类)没有实现任何业务接口,
 * 但是得实现一个MethodInterceptor的接口
 * @author Mars
 *CGLIB可以生成目标类的子类,并重写父类的非final的方法
 */
public class CGlibProxyFactory implements MethodInterceptor {
	Object targetObject=null;//代理目标对象
	
	public Object createProxyIntance(Object targetObject){
		this.targetObject = targetObject; 
		Enhancer enhancer = new Enhancer(); //该类用于生成代理对象
		//设置一个父类,也就是目标类
		/**
		 * 继承目标类后会产生一个子类,会覆盖所有非final方法,再添加些自身的代码
		 */
		enhancer.setSuperclass(this.targetObject.getClass()); // 设置父类
		//设置回调方法
		enhancer.setCallback(this); //设置回调函数为本身
		return enhancer.create();
		
	}
	
	/**
	 * 当代理对象调用时可以回调这个方法
	 * Object proxy:代理对象本身
	 * Method method:被拦截到的方法
	 * Object[] args:方法的输入参数
	 * MethodProxy methodProxy:方法的代理对象
	 * 环绕通知:
	 * 	在一个方法执行之前和之后执行。
	 *  它使得通知有机会既在一个方法执行之前又在执行之后运行。
	 *  并且,它可以决定这个方法在什么时候执行,如何执行,甚至是否执行。
	 *  环绕通知经常在在某线程安全的环境下,你需要在一个方法执行之前和之后共享某种状态的时候使用。
	 *  请尽量使用最简单的满足你需求的通知。
	 * (比如如果前置通知(before advice)也可以适用的情况下不要使用环绕通知)。
	 */
	@Override
	public Object intercept(Object proxy, Method method, Object[] args,
			MethodProxy methodProxy) throws Throwable {
		PersonServiceBean2 bean = (PersonServiceBean2)this.targetObject;
		
		Object result = null;//环绕通知
		if(bean.getUser() !=null){
			try {
				//所谓通知就相关业务方法
				//.......advice() -->前置通知
				result = methodProxy.invoke(targetObject, args);
				//.......afteradvice()--->后置通知
			} catch (Exception e) {
				// exceptionadvice()-->例外通知
			}finally{
				// finallyadvice()-->最终通知
			}
			
		}
		return result;
	}
}



测试类:

package junit.test;

import org.junit.BeforeClass;
import org.junit.Test;

import cn.itcast.aop.CGlibProxyFactory;
import cn.itcast.service.imp.PersonServiceBean2;


public class CGlibTest {
	@BeforeClass
	public static void setUpBeforeClass() throws Exception{
		
	}
	@Test public void proxyTest(){
		CGlibProxyFactory factory = new CGlibProxyFactory();
		//有无权限的两种情况
//		PersonServiceBean2 service = (PersonServiceBean2)factory.createProxyIntance(new PersonServiceBean2()); 
		PersonServiceBean2 service = (PersonServiceBean2)factory.createProxyIntance(new PersonServiceBean2("xxxx")); 
		service.save("999999999");
	}
}


总结:

AOP中概念:
Aspect(切面):指横切关注点的抽象即为切面,他与类类似,只是两者的关注点不一样,类是对物体特征的抽象,
而切面是横切关注点的抽象。(暂时理解为业务流程的,某环节的抽象)。
joinpoint(连接点):所谓连接点是指那些被拦截到的点。在spring中,这些点指的是方法,因为spring只支持方法类型的连接点,实际上joinpoint还可以是field(注解)或是构造器。
Pointcut(切入点):所谓切入点是指我们要对这些joinpoint进行拦截的定义。(暂时理解为拦截所有业务方法)
Advice(通知):所谓通知是指拦截到joinpoint之后索要做的事情就是通知,通知分为前置通知、后置通知、异常通知、最终通知、环绕通知
Target(目标对象):代理的目标对象
Weave(织入):指将aspects应用到target对象并导致proxy对象创建的过程称为织入。
Introduction(引入):在不修改类代码的前提下,Introduction可以在运行期为类动态的添加一些方法或Field(注解 )

有关通知的相关可以参考:

http://blog.csdn.net/frank3g/article/details/6323497

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值