黑马程序员-代理和AOP

       ------------- android培训java培训、java学习型技术博客、期待与您交流! ------------
 

         纠结了2周的代理, 终于在今晚告一段落了,  废话不多说,开始总结:

        所谓的代理,其实就是通过一个对象去调用其封装好的某一个方法,它在其他类的各个方法中增加了一些系统功能,例如,异常处理、日志、计算方法的运行时间、事物管理、等等。

        通常情况下,我们都是采用动态代理,我们可以自定义一个目标类,借由代理类来实现它。

        编写一个与目标类具有相同接口的代理类,代理类的每个方法调用目标类的相同方法,并在调用方法时加上系统功能的代码。

        如果采用工厂模式和配置文件的方式进行管理,则不需要修改客户端程序,在配置文件中配置是使用目标类、还是代理类,这样以后很容易切换,譬如,想要日志功能时就配置代理类,否则配置目标类,这样,增加系统功能很容易,以后运行一段时间后,又想去掉系统功能也很容易。

        代理分为两种,静态代理以及动态代理
        
        静态代理:
        系统中的各种接口的类增加代理功能,那将需要太多的代理类,全部采用静态代理方式,也就是说,我们需要一个个的将类写死,比如说要实现什么样的接口,接口里所带的参数等等, 要写死,这样很不利于开发。
        
        动态代理:
        于是就产生出了动态代理的概念,由我们自己去配置一个类,交由Java虚拟机去识别。(请看概念)
        JVM可以在运行期动态生成出类的字节码,这种动态生成的类往往被用作代理类,即动态代理类。
        JVM生成的动态类必须实现一个或多个接口,所以,JVM生成的动态类只能用作具有相同接口的目标类的代理。
CGLIB库可以动态生成一个类的子类,一个类的子类也可以用作该类的代理,所以,如果要为一个没有实现接口的类生成动态代理类,那么可以使用CGLIB库。
        代理类的各个方法中通常除了要调用目标的相应方法和对外返回目标返回的结果外,还可以在代理方法中的如下四个位置加上系统功能代码:
        1.在调用目标方法之前
        2.在调用目标方法之后
        3.在调用目标方法前后
        4.在处理目标方法异常的catch块中
  

        获取代理类

//,
Class  clazzProxy1  =  Proxy. getProxyClass( Collection. class. getClassLoader(),  Collection. class);   //打印结果是 $Proxy0
 

       获取代理类的构造方法

         Constructor[]  constructors  =  clazzProxy1. getConstructors();  //
        
         for( Constructor  constructor :  constructors){
             
              String  name  =  constructor. getName();  //
             
              StringBuilder  sBuilder  =  new  StringBuilder( name);  //
             
              sBuilder. append( '(');
             
              Class[]  clazzParams  =  constructor. getParameterTypes();  //
             
              for( Class  clazzParam :  clazzParams){
                  
                   sBuilder. append( clazzParam. getName()). append( ',');
                  
             }
             
              if( clazzParams != null  &&  clazzParams. length  !=  0)   // 
             
                   sBuilder. deleteCharAt( sBuilder. length() -1);
                  
              sBuilder. append( ')');
             
              System. out. println( sBuilder. toString()); //  xxx(xx);
             
              //$Proxy0(java.lang.reflect.InvocationHandler)  
             
              //InvocationHandler ,
             
              //,InvocationHandler
             
        }
 

        返回代理类里的各个方法

         for( Method  method :  methods){
             
              String  name  =  method. getName();
             
              StringBuilder  sBuilder  =  new  StringBuilder( name);
             
              sBuilder. append( '(');
             
              Class[]  clazzParams  =  method. getParameterTypes();
             
              for( Class  clazzParam :  clazzParams){
                  
                   sBuilder. append( clazzParam. getName()). append( ',');
                  
             }
              if( clazzParams != null  &&  clazzParams. length  !=  0)
             
                   sBuilder. deleteCharAt( sBuilder. length() -1);
                  
              sBuilder. append( ')');
             
              System. out. println( sBuilder. toString());    
             
        }  //代码同构造方法  不做解释
         
        创建代理的实例化对象  以Collection 为例
    
 
     class  MyInvocationHander1  implements  InvocationHandler{
        
              public  Object  invoke( Object  proxyMethod  methodObject[]  args)
                        throws  Throwable {
                            
                   // TODO Auto-generated method stub
                   return  null;
             }
        
        }
         Collection  proxy1  = ( Collection) constructor. newInstance( new  MyInvocationHander1());
        
         //InvocationHandlder,
        
         //InvocationHandlder
        
         System. out. println( proxy1);
        
         proxy1. clear();
        
//      proxy1.size();  //,invokenull
 
 
         Collection  proxy2  = ( Collection) constructor. newInstance( new  InvocationHandler(){  //
              public  Object  invoke( Object  proxyMethod  methodObject[]  args)
                        throws  Throwable {
                            
                   return  null;
             }
             
        });  //同上 不解释
 
 
 
/*
    ,  
*/
Collection  proxy3  = ( Collection) Proxy. newProxyInstance(
    
                 Collection. class. getClassLoader(),   //目标类的类加载器
                  
                   new  Class[]{ Collection. class},  //目标类
                  
                   new  InvocationHandler(){
                       
                        ArrayList  target  =  new  ArrayList();   
                       
                        public  Object  invoke( Object  proxyMethod  methodObject[]  args)
                                  throws  Throwable {
                            
                             System. out. println( "ArrayListHashCode: " + target. hashCode());
                            
                             Object  retVal  =  method. invoke( targetargs); 
                            
                             System. out. println( retVal. getClass(). getName());
                            
                             return  retVal;                      
                       }
                  }
                  );
        
         proxy3. add( "zxx");  //addinvoke
        
         proxy3. add( "lhm");
        
         proxy3. add( "bxd");
        
         System. out. println( proxy3. size());
        
         //System.out.println(proxy3.getClass().getName());());
        
         //objecthashCode equals toStringInvocationHandler 
 
        为代理添加一些自定义的功能,那么,这个接口我们可以自定义,比如:计算方法的时间
        首先需要一个接口。
public  class  ProxyFactoryBean {
     private  Advice  advice;   //
    
     private  Object  target//
    
    
     public  Advice  getAdvice() {
         return  advice;
    }
     public  void  setAdvice( Advice  advice) {
         this. advice  =  advice;
    }
     public  Object  getTarget() {
         return  target;
    }
     public  void  setTarget( Object  target) {
         this. target  =  target;
    }
     public  Object  getProxy() {
        
         // TODO Auto-generated method stub
         Object  proxy3  =  Proxy. newProxyInstance(
             
                   target. getClass(). getClassLoader(),  //
                  
                   target. getClass(). getInterfaces(), //
                  
                   new  InvocationHandler(){
                  
                        public  Object  invoke( Object  proxyMethod  methodObject[]  args)
                                  throws  Throwable {
                             advice. beforeMethod( method);  //,
                            
                             //invoke,,set
                            
                             //set使
                            
                             Object  retVal  =  method. invoke( targetargs);
                            
                             advice. afterMethod( method);  //
                            
                             return  retVal;                      
                            
                       }
                  }
                  );
         return  proxy3;
    }
}
 
 AOP的定义
Spring框架里有一个AOP的概念, 所以的AOP,是面向切面的编程, 也就是说,在框架的基础上添加事物等一系列的功能。

 
根据配置文件获取到动态代理的例子:
 
public  class  ProxyFactoryBean {
     private  Advice  advice//
    
     private  Object  target//
    
     public  Advice  getAdvice() {
        
         return  advice;
    }
     public  void  setAdvice( Advice  advice) {
        
         this. advice  =  advice;
    }
     public  Object  getTarget() {
        
         return  target;
    }
     public  void  setTarget( Object  target) {
        
         this. target  =  target;
    }
     public  Object  getProxy() {  //同上, 不解释
         Object  proxy3  =  Proxy. newProxyInstance(
             
                   target. getClass(). getClassLoader(),
        
                   target. getClass(). getInterfaces(),
                  
                   new  InvocationHandler(){
                  
                        public  Object  invoke( Object  proxyMethod  methodObject[]  args)
                                  throws  Throwable {
                             advice. beforeMethod( method);
                            
                             Object  retVal  =  method. invoke( targetargs);
                            
                             advice. afterMethod( method);
                            
                             return  retVal;                      
                            
                       }
                  }
                  );
         return  proxy3;
    }
 
 
 
public  class  BeanFactory {
    
     Properties  props  =  new  Properties();
    
     public  BeanFactory( InputStream  ips){
        
         try {
             
              props. load( ips);   //
             
        }  catch ( IOException  e) {
             
              e. printStackTrace();
        }
    }
    
     public  Object  getBean( String  name){  //
        
         String  className  =  props. getProperty( name); 
        
         Object  bean  =  null;
        
         try {
             
              Class  clazz  =  Class. forName( className);  //,
             
              //,BEAN
             
              bean  =  clazz. newInstance();
             
        }  catch ( Exception  e) {
             
              e. printStackTrace();
        } 
        
         if( bean  instanceof  ProxyFactoryBean){
             
              Object  proxy  =  null;
             
              ProxyFactoryBean  proxyFactoryBean  = ( ProxyFactoryBean) bean//
             
              try {
                  
                   //
                  
                   Advice  advice  = ( Advice) Class. forName( props. getProperty( name  +  ".advice")). newInstance();
                  
                   //
                  
                   Object  target  =  Class. forName( props. getProperty( name  +  ".target")). newInstance();
                  
                   //set
                  
                   proxyFactoryBean. setAdvice( advice);
                  
                   proxyFactoryBean. setTarget( target);
                  
                   //,
                  
                   proxy  =  proxyFactoryBean. getProxy();
                  
             }  catch ( Exception  e) {
                  
                   e. printStackTrace();
                  
             }
             
              return  proxy;
             
        }
        
         return  bean;
        
    }
    
}
 
 

------------- android培训java培训、java学习型技术博客、期待与您交流! ------------

详情请查看:http://edu.csdn.net/

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值