动态代理

JDK与CGLIB动态代理
本文介绍了Java中两种动态代理技术:JDK动态代理和CGLIB代理。JDK动态代理主要用于接口的代理,而CGLIB则通过继承方式实现对类的代理。文章详细展示了两种代理的具体实现代码及应用场景。

1、JDK的动态代理

JDK的动态代理只针对接口进行操作,对未实现接口的类无法进行; 当未实现接口时,采用CGLIB来完成,其原理是继承被代理的类,在对非final的方法进行了重写。
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

import cn.itcast.service.impl.PersonServiceBean;

public class JDKProxyFactory implements InvocationHandler{
  private Object targetObject;
  
  public Object createProxyIntance(Object targetObject){
    this.targetObject = targetObject;
    return Proxy.newProxyInstance(this.targetObject.getClass().getClassLoader(), 
        this.targetObject.getClass().getInterfaces(), this);
  }

  public Object invoke(Object proxy, Method method, Object[] args)
      throws Throwable {//环绕通知
    PersonServiceBean bean = (PersonServiceBean) this.targetObject;
    Object result = null
    if(bean.getUser()!=null){
      //..... advice()-->前置通知
      try {
        result = method.invoke(targetObject, args);
        // afteradvice() -->后置通知
      } catch (RuntimeException e) {
        //exceptionadvice()--> 例外通知
      }finally{
        //finallyadvice(); -->最终通知
      }
    }
    return result;
  }

}
被代理接口:PersonService.java
public interface PersonService {
  public void save(String name);
  public void update(String name, Integer personid);
  public String getPersonName(Integer personid);
}
被代理类:PersonServiceBean.java

public class PersonServiceBean implements PersonService{
  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()方法");
  }

}
 
客户端调用:
public class AOPTest {

  @BeforeClass
  public static void setUpBeforeClass() throws Exception {
  }

  @Test public void proxyTest(){
    JDKProxyFactory factory = new JDKProxyFactory();
    PersonService service = (PersonService) factory.createProxyIntance(new PersonServiceBean("xxx"));
    service.save("888");
  }
  
  @Test public void proxyTest2(){
    CGlibProxyFactory factory = new CGlibProxyFactory();
    PersonServiceBean service = (PersonServiceBean) factory.createProxyIntance(new PersonServiceBean("xxx"));
    service.save("999");
  }
}
 

2、CGLIB进行调用

import java.lang.reflect.Method;

import cn.itcast.service.impl.PersonServiceBean;

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 targetObject;
  
  public Object createProxyIntance(Object targetObject){
    this.targetObject = targetObject;
    Enhancer enhancer = new Enhancer();
    enhancer.setSuperclass(this.targetObject.getClass());//非final
    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;
  }
}
 
对CGLIB代理进行测试:
public class AOPTest {

  @BeforeClass
  public static void setUpBeforeClass() throws Exception {
  }

  @Test public void proxyTest(){
    JDKProxyFactory factory = new JDKProxyFactory();
    PersonService service = (PersonService) factory.createProxyIntance(new PersonServiceBean("xxx"));
    service.save("888");
  }
  
  @Test public void proxyTest2(){
    CGlibProxyFactory factory = new CGlibProxyFactory();
    PersonServiceBean service = (PersonServiceBean) factory.createProxyIntance(new PersonServiceBean("xxx"));
    service.save("999");
  }
}


本文转自 tianya23 51CTO博客,原文链接:http://blog.51cto.com/tianya23/376847,如需转载请自行联系原作者
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值