代理

使用代理模式必须要让代理类和目标类实现相同的接口,客户端通过代理类来调用目标方法,代理类会将所有的方法调用分派到目标对象上反射执行,还可以在分派过程中添加"前置通知"和后置处理(如在调用目标方法前校验权限,在调用完目标方法后打印日志等)等功能。

1.静态代理

代理类与被代理类实现同一个接口

在被代理类作为代理类中的属性,重写默认构造器

接口

public interface Count {

    // 查看账户方法
    public void queryCount();

    // 修改账户方法
    public void updateCount();

}

被代理类

public class CountImpl implements Count{
    public void queryCount() {
        System.out.println("查看账户方法...");

    }

    public void updateCount() {
        System.out.println("修改账户方法...");

    }
}

代理类

public class CountProxy implements Count {
    private CountImpl countImpl;    
    
    /**  
     * 覆盖默认构造器  
     *   
     * @param countImpl  
     */    
    public CountProxy(CountImpl countImpl) {    
        this.countImpl = countImpl;    
    }    
    
    public void queryCount() {
        System.out.println("事务处理之前");    
        // 调用委托类的方法;    
        countImpl.queryCount();    
        System.out.println("事务处理之后");    
    }    
    
    public void updateCount() {
        System.out.println("事务处理之前");    
        // 调用委托类的方法;    
        countImpl.updateCount();    
        System.out.println("事务处理之后");    
    
    }    
    
}     

测试类

public class TestCount {
    public static void main(String[] args) {    
        CountImpl countImpl = new CountImpl();    
        CountProxy countProxy = new CountProxy(countImpl);    
        countProxy.updateCount();    
        countProxy.queryCount();    
    
    }    
}  

2.jdk动态代理(实现InvocationHandler接口)

实现原理:JDK的动态代理,就是在程序运行的过程中,根据被代理的接口来动态生成代理类的class文件,并加载运行的过程。

Proxy0.class

Proxy0继承Proxy类,并实现UserService接口,在获得代理对象时向上转型,得到UserService 引用。

 

生成Proxy0.class文件

 

  byte[]classFile =ProxyGenerator.generateProxyClass("Proxy0",BookImpl.class.getInterfaces());

        File file =new File("E:/Proxy0.class");

        FileOutputStream fos =new FileOutputStream(file);

        fos.write(classFile);

        fos.flush();

        fos.close();

 

 

 

public class MyInvocationHandler implements InvocationHandler {

    private Object target;
    public MyInvocationHandler(Object target){
        this.target = target;
    }

    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.println("----------before----------");
        Object invoke = method.invoke(target, args);
        System.out.println("----------after----------");
        return invoke;
    }

    public Object getProxy(){
        return Proxy.newProxyInstance(Thread.currentThread().getContextClassLoader(),this.target.getClass().getInterfaces(),this);
    }
}

接口

public interface UserService{
      
    /** 
     * 目标方法  
     */  
    public void add(String name);
}

实现类

public class UserServiceImpl implements UserService{
    public void add( String name) {
     System.out.println("----------add----------");  
          
    }  
}

测试

public class ProxyTest{
      
    @Test
    public void testProxy() throws Throwable{  
        //实例化目标对象  
        UserService userService=new UserServiceImpl();  
          
        //实例化Invocation  
        MyInvocationHandler invocationHandler=new MyInvocationHandler(userService);  
          
        //根据目标生成代理对象  
        UserService proxy=(UserService)invocationHandler.getProxy();  
          
        //调用代理对象方法  
        proxy.add("-----------------------><--------------------------------");
    }  
}  

3.cglib代理

cglib是针对类来实现代理的,他的原理是对指定的目标类生成一个子类,并覆盖其中方法实现增强,但因为采用的是继承,所以不能对final修饰的类进行代理

定义代理实现 MethodInterceptor接口

被代理类

public class BookFacadeImpl {
    public void addBook() {    
        System.out.println("增加图书的普通方法...");    
    }    
}   

代理类

public class BookFacadeCglib implements MethodInterceptor {
    private Object target;    
    
    /**  
     * 创建代理对象  
     *   
     * @param target  
     * @return  
     */    
    public Object getInstance(Object target) {    
        this.target = target;    
        Enhancer enhancer = new Enhancer();
        enhancer.setSuperclass(this.target.getClass());    
        // 回调方法    
        enhancer.setCallback(this);    
        // 创建代理对象    
        return enhancer.create();    
    }


    // 回调方法
    public Object intercept(Object obj, Method method, Object[] args,
                            MethodProxy proxy) throws Throwable {
        System.out.println("事物开始");
        proxy.invokeSuper(obj, args);
        System.out.println("事物结束");
        return null;


    }
}

测试

public class TestCglib {
        
    public static void main(String[] args) {    
        BookFacadeCglib cglib=new BookFacadeCglib();    
        BookFacadeImpl bookCglib=(BookFacadeImpl)cglib.getInstance(new BookFacadeImpl());    
        bookCglib.addBook();    
    }    
}    

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值