第一种:使用JDK中的Proxy技术实现AOP功能
public class JDKProxy implements InvocationHandler {
private Object targetObject;//代理的目标对象public Object createProxyInstance(Object targetObject){
this.targetObject = targetObject;
/*
* 第一个参数设置代码使用的类装载器,一般采用跟目标类相同的类装载器
* 第二个参数设置代理类实现的接口
* 第三个参数设置回调对象,当代理对象的方法被调用时,会委派给该参数指定对象的invoke方法
*/
return Proxy.newProxyInstance(this.targetObject.getClass().getClassLoader(),
this.targetObject.getClass().getInterfaces(), this);
}
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
return method.invoke(this.targetObject, args);//把方法调用委派给目标对象
}
}
当目标类实现了接口,我们可以使用jdk的Proxy来生成代理对象。
- package cn.itm.service;
- public interface PersonService {
- public void save(String name);
- public void update(String name,Integer personid);
- public String getPersonName(Integer personid);
- }
- package cn.itm.service.impl;
- import cn.itm.service.PersonService;
- /**
- * 对这里面的所有方法 实施拦截,拦截到这个方式之后,我们判断,用户是否为 null,如果为null,就没有权限去调用这里面的方法。
- * @author Administrator
- *
- */
- public class PersonServiceBean implements PersonService {
- private String user = null;
- public String getUser() {
- return user;
- }
- public PersonServiceBean(){}
- public PersonServiceBean(String user){
- this.user = user;
- }
- @Override
- public String getPersonName(Integer personid) {
- System.out.println("我是 getPersonName()方法 ");
- return "xxx";
- }
- @Override
- public void save(String name) {
- System.out.println("我是 save() 方法");
- }
- @Override
- public void update(String name, Integer personid) {
- System.out.println("我是 update() 方法");
- }
- }
- package cn.itm.aop;
- import java.lang.reflect.InvocationHandler;
- import java.lang.reflect.Method;
- import java.lang.reflect.Proxy;
- import cn.itm.service.impl.PersonServiceBean;
- public class JDKProxyFactory implements InvocationHandler{
- private Object targetObject;
- /**
- * 调用对象 会 被this 拦截到。拦截到后,他会执行invoke() 方法 也就是说:客户端调用代理对象业务方法的时候,代理对象就会执行 InvocationHandler 找 invoke()方法
- *
- * invoke方法就会 把 method的调用 委派给目标对象。
- *
- * @param targetObject
- * @return
- */
- public Object createProxyInstance(Object targetObject){
- this.targetObject = targetObject;
- return Proxy.newProxyInstance(
- this.targetObject.getClass().getClassLoader(),
- this.targetObject.getClass().getInterfaces(),
- this
- );
- }
- /**
- *
- * @param proxy
- * @param method : 代表被拦截到的方法,
- * @param args : 代表方法的输入参数。
- * @return
- * @throws Throwable
- */
- public Object invoke(Object proxy, Method method, Object[] args)
- throws Throwable {
- PersonServiceBean bean = (PersonServiceBean)this.targetObject;
- Object result = null;
- if(bean.getUser() != null){ // 代表如果有权限。
- // 委派给目标对象。
- result = method.invoke(targetObject, args);
- }
- return result;
- }
- }
- package junit.test;
- import org.junit.BeforeClass;
- import org.junit.Test;
- import cn.itm.aop.JDKProxyFactory;
- import cn.itm.service.PersonService;
- import cn.itm.service.impl.PersonServiceBean;
- public class AOPTest {
- @BeforeClass
- public static void setUpBeforeClass() throws Exception {
- }
- @Test public void proxyTest(){
- JDKProxyFactory factory = new JDKProxyFactory();
- // 注意要使用接口 来饮用代理对象。
- PersonService personService = (PersonService)factory.createProxyInstance(new PersonServiceBean("XXX"));
- personService.save("999");
- }
- }
ok,成功。
第二种:使用cglib
public class CGLIBProxy implements MethodInterceptor {
private Object targetObject;//代理的目标对象
public Object createProxyInstance(Object targetObject){
this.targetObject = targetObject;
Enhancer enhancer = new Enhancer();//该类用于生成代理对象
enhancer.setSuperclass(this.targetObject.getClass());//设置父类
enhancer.setCallback(this);//设置回调用对象为本身
return enhancer.create();
}
public Object intercept(Object proxy, Method method, Object[] args,
MethodProxy methodProxy) throws Throwable {
return methodProxy.invoke(this.targetObject, args);
}
}
CGLIB可以生成目标类的子类,并重写父类非final修饰符的方法。
代码示例:
不用实现接口
- package cn.itm.service.impl;
- /**
- * 对这里面的所有方法 实施拦截,拦截到这个方式之后,我们判断,用户是否为 null,如果为null,就没有权限去调用这里面的方法。
- * @author Administrator
- *
- */
- public class PersonServiceBean{
- private String user = null;
- public String getUser() {
- return user;
- }
- public PersonServiceBean(){}
- public PersonServiceBean(String user){
- this.user = user;
- }
- public String getPersonName(Integer personid) {
- System.out.println("我是 getPersonName()方法 ");
- return "xxx";
- }
- public void save(String name) {
- System.out.println("我是 save() 方法");
- }
- public void update(String name, Integer personid) {
- System.out.println("我是 update() 方法");
- }
- }
使用cglib实现:
- package cn.itm.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.itm.service.impl.PersonServiceBean;
- public class CGLIBProxyFactory implements MethodInterceptor{
- private Object targetObject;
- public Object createProxyInstance(Object targetObject){
- this.targetObject = targetObject;
- Enhancer enhancer = new Enhancer();//该类用于生成代理对象
- enhancer.setSuperclass(this.targetObject.getClass());//设置父类
- enhancer.setCallback(this);//设置回调用对象为本身
- return enhancer.create(); // 创建代理对象。
- }
- public Object intercept(Object proxy, Method method, Object[] args,
- MethodProxy methodProxy) throws Throwable {
- PersonServiceBean bean = (PersonServiceBean)this.targetObject;
- Object result = null;
- if(bean.getUser() != null){ // 代表如果有权限。
- // 委派给目标对象。
- result = methodProxy.invoke(targetObject, args);
- }
- return result;
- }
- }
测试类
- package junit.test;
- import org.junit.BeforeClass;
- import org.junit.Test;
- import cn.itm.aop.CGLIBProxyFactory;
- import cn.itm.service.impl.PersonServiceBean;
- public class AOPTest {
- @BeforeClass
- public static void setUpBeforeClass() throws Exception {
- }
- @Test public void cglibproxyTest(){
- CGLIBProxyFactory factory = new CGLIBProxyFactory();
- // 注意要使用接口 来饮用代理对象。
- PersonServiceBean personServiceBean = (PersonServiceBean)factory.createProxyInstance(new PersonServiceBean(/*"XXX"*/));
- personServiceBean.save("CGLIB----> 999");
- }
- }