java动态***(JDK和cglib)

JAVA的动态*** 
***模式 
***模式是常用的java设计模式,他的特征是***类与委托类有同样的接口,***类主要负责为委托类预处理消息、过滤消息、把消息转发给委托类,以及事后处理消息等。***类与委托类之间通常会存在关联关系,一个***类的对象与一个委托类的对象关联,***类的对象本身并不真正实现服务,而是通过调用委托类的对象的相关方法,来提供特定的服务。 
按照***的创建时期,***类可以分为两种。 
静态***:由程序员创建或特定工具自动生成源代码,再对其编译。在程序运行前,***类的.class文件就已经存在了。 
动态***:在程序运行时,运用反射机制动态创建而成。 

 

首先看一下静态***: 

1、Count.java 

package net.battier.dao;  
  
/** 
 * 定义一个账户接口 
 *  
 * @author Administrator 
 *  
 */  
public interface Count {  
    // 查看账户方法  
    public void queryCount();  
  
    // 修改账户方法  
    public void updateCount();  
  
}  
2、CountImpl.java 
package net.battier.dao.impl;  
  
import net.battier.dao.Count;  
  
/** 
 * 委托类(包含业务逻辑) 
 *  
 * @author Administrator 
 *  
 */  
public class CountImpl implements Count {  
  
    @Override  
    public void queryCount() {  
        System.out.println("查看账户方法...");  
  
    }  
  
    @Override  
    public void updateCount() {  
        System.out.println("修改账户方法...");  
  
    }  
  
}  
  
、CountProxy.java  
package net.battier.dao.impl;  
  
import net.battier.dao.Count;  
  
/** 
 * 这是一个***类(增强CountImpl实现类) 
 *  
 * @author Administrator 
 *  
 */  
public class CountProxy implements Count {  
    private CountImpl countImpl;  
  
    /** 
     * 覆盖默认构造器 
     *  
     * @param countImpl 
     */  
    public CountProxy(CountImpl countImpl) {  
        this.countImpl = countImpl;  
    }  
  
    @Override  
    public void queryCount() {  
        System.out.println("事务处理之前");  
        // 调用委托类的方法;  
        countImpl.queryCount();  
        System.out.println("事务处理之后");  
    }  
  
    @Override  
    public void updateCount() {  
        System.out.println("事务处理之前");  
        // 调用委托类的方法;  
        countImpl.updateCount();  
        System.out.println("事务处理之后");  
  
    }  
  
}  
3、TestCount.java 
package net.battier.test;  
  
import net.battier.dao.impl.CountImpl;  
import net.battier.dao.impl.CountProxy;  
  
/** 
 *测试Count类 
 *  
 * @author Administrator 
 *  
 */  
public class TestCount {  
    public static void main(String[] args) {  
        CountImpl countImpl = new CountImpl();  
        CountProxy countProxy = new CountProxy(countImpl);  
        countProxy.updateCount();  
        countProxy.queryCount();  
  
    }  
}  

观察代码可以发现每一个***类只能为一个接口服务,这样一来程序开发中必然会产生过多的***,而且,所有的***操作除了调用的方法不一样之外,其他的操作都一样,则此时肯定是重复代码。解决这一问题最好的做法是可以通过一个***类完成全部的***功能,那么此时就必须使用动态***完成。 
再来看一下动态***: 
JDK动态***中包含一个类和一个接口: 
InvocationHandler接口: 
public interface InvocationHandler { 
public Object invoke(Object proxy,Method method,Object[] args) throws Throwable; 

参数说明: 
Object proxy:指被***的对象。 
Method method:要调用的方法 
Object[] args:方法调用时所需要的参数 

可以将InvocationHandler接口的子类想象成一个***的最终操作类,替换掉ProxySubject。 

Proxy类: 
Proxy类是专门完成***的操作类,可以通过此类为一个或多个接口动态地生成实现类,此类提供了如下的操作方法: 
public static Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces, 
InvocationHandler h) 
                               throws IllegalArgumentException 
参数说明: 
ClassLoader loader:类加载器 
Class<?>[] interfaces:得到全部的接口 
InvocationHandler h:得到InvocationHandler接口的子类实例 

Ps:类加载器 
在Proxy类中的newProxyInstance()方法中需要一个ClassLoader类的实例,ClassLoader实际上对应的是类加载器,在Java中主要有一下三种类加载器; 
Booststrap ClassLoader:此加载器采用C++编写,一般开发中是看不到的; 
Extendsion ClassLoader:用来进行扩展类的加载,一般对应的是jre\lib\ext目录中的类; 
AppClassLoader:(默认)加载classpath指定的类,是最常使用的是一种加载器。 

动态*** 
与静态***类对照的是动态***类,动态***类的字节码在程序运行时由Java反射机制动态生成,无需程序员手工编写它的源代码。动态***类不仅简化了编程工作,而且提高了软件系统的可扩展性,因为Java 反射机制可以生成任意类型的动态***类。java.lang.reflect 包中的Proxy类和InvocationHandler 接口提供了生成动态***类的能力。 

动态***示例: 
1、BookFacade.java 

package net.battier.dao;  
  
public interface BookFacade {  
    public void addBook();  
}  
2、BookFacadeImpl.java 
package net.battier.dao.impl;  
  
import net.battier.dao.BookFacade;  
  
public class BookFacadeImpl implements BookFacade {  
  
    @Override  
    public void addBook() {  
        System.out.println("增加图书方法。。。");  
    }  
  
}  
  
、BookFacadeProxy.java  
  
package net.battier.proxy;  
  
import java.lang.reflect.InvocationHandler;  
import java.lang.reflect.Method;  
import java.lang.reflect.Proxy;  
  
/** 
 * JDK动态******类 
 *  
 * @author student 
 *  
 */  
public class BookFacadeProxy implements InvocationHandler {  
    private Object target;  
    /** 
     * 绑定委托对象并返回一个***类 
     * @param target 
     * @return 
     */  
    public Object bind(Object target) {  
        this.target = target;  
        //取得***对象  
        return Proxy.newProxyInstance(target.getClass().getClassLoader(),  
                target.getClass().getInterfaces(), this);   //要绑定接口(这是一个缺陷,cglib弥补了这一缺陷)  
    }  
  
    @Override  
    /** 
     * 调用方法 
     */  
    public Object invoke(Object proxy, Method method, Object[] args)  
            throws Throwable {  
        Object result=null;  
        System.out.println("事物开始");  
        //执行方法  
        result=method.invoke(target, args);  
        System.out.println("事物结束");  
        return result;  
    }  
  
}  
3、TestProxy.java 
  1. package net.battier.test;  
  2.   
  3. import net.battier.dao.BookFacade;  
  4. import net.battier.dao.impl.BookFacadeImpl;  
  5. import net.battier.proxy.BookFacadeProxy;  
  6.   
  7. public class TestProxy {  
  8.   
  9.     public static void main(String[] args) {  
  10.         BookFacadeProxy proxy = new BookFacadeProxy();  
  11.         BookFacade bookProxy = (BookFacade) proxy.bind(new BookFacadeImpl());  
  12.         bookProxy.addBook();  
  13.     }  
  14.   
  15. }  

 

但是,JDK的动态***依靠接口实现,如果有些类并没有实现接口,则不能使用JDK***,这就要使用cglib动态***了。 

Cglib动态*** 
JDK的动态***机制只能***实现了接口的类,而不能实现接口的类就不能实现JDK的动态***,cglib是针对类来实现***的,他的原理是对指定的目标类生成一个子类,并覆盖其中方法实现增强,但因为采用的是继承,所以不能对final修饰的类进行***。 
示例 
1、BookFacadeCglib.java 

  1. package net.battier.dao;  
  2.   
  3. public interface BookFacade {  
  4.     public void addBook();  
  5. }  

 

2、BookCadeImpl1.java 

  1. package net.battier.dao.impl;  
  2.   
  3. /** 
  4.  * 这个是没有实现接口的实现类 
  5.  *  
  6.  * @author student 
  7.  *  
  8.  */  
  9. public class BookFacadeImpl1 {  
  10.     public void addBook() {  
  11.         System.out.println("增加图书的普通方法...");  
  12.     }  
  13. }  


3、BookFacadeProxy.java 

  1. package net.battier.proxy;  
  2.   
  3. import java.lang.reflect.Method;  
  4.   
  5. import net.sf.cglib.proxy.Enhancer;  
  6. import net.sf.cglib.proxy.MethodInterceptor;  
  7. import net.sf.cglib.proxy.MethodProxy;  
  8.   
  9. /** 
  10.  * 使用cglib动态*** 
  11.  *  
  12.  * @author student 
  13.  *  
  14.  */  
  15. public class BookFacadeCglib implements MethodInterceptor {  
  16.     private Object target;  
  17.   
  18.     /** 
  19.      * 创建***对象 
  20.      *  
  21.      * @param target 
  22.      * @return 
  23.      */  
  24.     public Object getInstance(Object target) {  
  25.         this.target = target;  
  26.         Enhancer enhancer = new Enhancer();  
  27.         enhancer.setSuperclass(this.target.getClass());  
  28.         // 回调方法  
  29.         enhancer.setCallback(this);  
  30.         // 创建***对象  
  31.         return enhancer.create();  
  32.     }  
  33.   
  34.     @Override  
  35.     // 回调方法  
  36.     public Object intercept(Object obj, Method method, Object[] args,  
  37.             MethodProxy proxy) throws Throwable {  
  38.         System.out.println("事物开始");  
  39.         proxy.invokeSuper(obj, args);  
  40.         System.out.println("事物结束");  
  41.         return null;  
  42.   
  43.   
  44.     }  
  45.   
  46. }  


4、TestCglib.java 

  1. package net.battier.test;  
  2.   
  3. import net.battier.dao.impl.BookFacadeImpl1;  
  4. import net.battier.proxy.BookFacadeCglib;  
  5.   
  6. public class TestCglib {  
  7.       
  8.     public static void main(String[] args) {  
  9.         BookFacadeCglib cglib=new BookFacadeCglib();  
  10.         BookFacadeImpl1 bookCglib=(BookFacadeImpl1)cglib.getInstance(new BookFacadeImpl1());  
  11.         bookCglib.addBook();  
  12.     }  
  13. }  
转自:http://www.cnblogs.com/jqyp/archive/2010/08/20/1805041.html


注意!此信息未认证,请谨慎判断信息的真实性!

全部评论
空

相关内容推荐

头像
点赞 评论 收藏
转发
头像
点赞 评论 收藏
转发
头像
点赞 评论 收藏
转发
头像
点赞 评论 收藏
转发
头像
点赞 评论 收藏
转发
头像
2022-12-22 18:27
天津大学_2023
点赞 评论 收藏
转发
点赞 评论 收藏
转发
头像
点赞 评论 收藏
转发
头像
点赞 评论 收藏
转发
头像
点赞 评论 收藏
转发
头像
点赞 评论 收藏
转发
头像
点赞 评论 收藏
转发
头像
点赞 评论 收藏
转发
点赞 评论 收藏
转发
头像
点赞 评论 收藏
转发
点赞 收藏 评论
分享

全站热榜

正在热议