码迷,mamicode.com
首页 > 编程语言 > 详细

Spring(十)通过动态代理(JDK的Proxy)和cglib实现AOP技术

时间:2015-07-25 12:29:56      阅读:142      评论:0      收藏:0      [点我收藏+]

标签:

目标对象的所有接口方法

package test.spring.service;

public interface PersonService {

	public String getPersonName(Integer id);

	public void save(String name);

}

目标对象

package test.spring.service.impl;

import test.spring.service.PersonService;

//代理对象实现目标对象所有接口
public class PersonServiceBean implements PersonService {

	private String user = null;

	public PersonServiceBean() {

	}

	public PersonServiceBean(String user) {
		super();
		this.user = user;
	}

	public String getUser() {
		return user;
	}

	public void setUser(String user) {
		this.user = user;
	}

	@Override
	public String getPersonName(Integer id) {
		// TODO Auto-generated method stub
		return "getPersonName";
	}

	@Override
	public void save(String name) {
		// TODO Auto-generated method stub
		System.out.println("save()->>" + name);
	}

}

代理对象,拦截所有业务方法,根据user是否为null判断用户是否有权限,有权限就允许执行业务方法,无权限就不执行。

package test.spring.aop;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

import test.spring.service.impl.PersonServiceBean;

public class ProxyFactory implements InvocationHandler {

	private Object proxyObject;

	// 创建代理对象实例
	public Object createProxyIntance(Object proxyObject) {
		this.proxyObject = proxyObject;
		/*
		 * 第一个参数:类装载器 
		 * 第二个参数:取得目标对象的接口,Proxy会将这些接口全部实现 
		 * 第三个参数:一个回调函数,确定实现哪个类的接口
		 */
		return Proxy.newProxyInstance(this.proxyObject.getClass()
				.getClassLoader(), this.proxyObject.getClass().getInterfaces(),
				this);
	}

	/*
	 * 第一个参数:代理对象 
	 * 第二个参数:被拦截到的方法 
	 * 第三个参数:方法的输入参数
	 */
	@Override
	public Object invoke(Object proxy, Method method, Object[] args)
			throws Throwable {
		PersonServiceBean personServiceBean = (PersonServiceBean) this.proxyObject;
		Object target = null;
		// user不为空说明有权限
		if (personServiceBean.getUser() != null) {
			// 把对代理对象方法的调用委派给目标对象
			target = method.invoke(proxyObject, args);
		}
		return target;
	}
}

权限测试

package test.spring.junit;

import static org.junit.Assert.*;

import org.junit.Test;

import test.spring.aop.ProxyFactory;
import test.spring.service.PersonService;
import test.spring.service.impl.PersonServiceBean;

public class AOPTest {

	@Test
	public void test() {
		ProxyFactory pFactory = new ProxyFactory();

		// PersonService pService=(PersonService)
		// pFactory.createProxyIntance(new PersonServiceBean("kkk"));

		// 改为默认函数pService.save("ppp")就执行不了,因为前面的user=null,相当于没有权限执行
		PersonService pService = (PersonService) pFactory
				.createProxyIntance(new PersonServiceBean());
		pService.save("ppp");
	}

}

技术分享

以上适用于目标对象实现了接口的情况,如果目标对象没有接口,就会选择用Cglib

首先导入cglib-nodep-2.1_3.jar

package test.spring.service.impl;

//代理对象实现目标对象所有接口
public class PersonServiceBean2 {

	private String user = null;

	public PersonServiceBean2() {

	}

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

	public String getUser() {
		return user;
	}

	public void setUser(String user) {
		this.user = user;
	}

	public void save(String name) {
		// TODO Auto-generated method stub
		System.out.println("save()->>" + name);
	}

}

package test.spring.aop;

import java.lang.reflect.Method;

import test.spring.service.impl.PersonServiceBean2;

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

//目标对象没有接口
public class CglibProxyFactory implements MethodInterceptor {
	private Object proxyObject;

	// 创建代理对象实例
	public Object createProxyIntance(Object proxyObject) {
		this.proxyObject = proxyObject;

		Enhancer enhancer = new Enhancer();
		/*
		 * 需设置父类,即目标类。创建的对象继承目标类,对目标类中
		 * 所有非final的所有方法进行覆盖,然后在覆盖的代码里面
		 * 添加一些自身的代码
		 */
		enhancer.setSuperclass(this.proxyObject.getClass());
		enhancer.setCallback((Callback) this);
		return enhancer.create();

	}

	/*
	 * 第一个参数:代理对象本身 
	 * 第二个参数:被拦截到的方法 
	 * 第三个参数:方法的参数 
	 * 第四个参数:方法的代理对象
	 */
	// 当代理对象的业务方法被回调的时候会调用这个方法
	@Override
	public Object intercept(Object proxy, Method method, Object[] args,
			MethodProxy methodProxy) throws Throwable {
		PersonServiceBean2 personServiceBean = (PersonServiceBean2) this.proxyObject;
		Object target = null;
		// user不为空说明有权限
		if (personServiceBean.getUser() != null) {
			// 把对方法的调用委派给目标对象
			target = methodProxy.invoke(proxyObject, args);
		}
		return target;
	}
}

package test.spring.junit;

import static org.junit.Assert.*;

import org.junit.Test;

import test.spring.aop.CglibProxyFactory;
import test.spring.aop.ProxyFactory;
import test.spring.service.PersonService;
import test.spring.service.impl.PersonServiceBean;
import test.spring.service.impl.PersonServiceBean2;

public class AOPTest2 {

	@Test
	public void test() {
		CglibProxyFactory pFactory = new CglibProxyFactory();

		// 此时PersonServiceBean没有接口
		PersonServiceBean2 pService = (PersonServiceBean2) pFactory
				.createProxyIntance(new PersonServiceBean2("kkk"));

		pService.save("ppp");
	}

}


版权声明:本文为博主原创文章,未经博主允许不得转载。如需转载,请注明出处:http://blog.csdn.net/lindonglian

Spring(十)通过动态代理(JDK的Proxy)和cglib实现AOP技术

标签:

原文地址:http://blog.csdn.net/lindonglian/article/details/47053987

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!