《Pro Spring》学习笔记之Introductions引用实例

引入的基本知识

Spring讲引用当成一种特殊的通知,具体讲些,是一种特殊的包围通知,因为引用只能用在类这一等级上,所以我们使用引用时不能用切入点,引入为类增加了新的接口实现,而切入点定义一个通知涉及的那些方法

背景

假设有如下案例,我们有一个javaBean,其中有setter和getter方法,当对象被属性被改变的以后,进行持久化操作,没有改变时候,不进行持久化操作,但是,我们如何确定javaBean是否真的进行改变了呢?如果用切入点的方式,我们就必须对每一个可能修改对象属性的方法都进行通知检查,这样会产生很多冗余代码,在这里使用引入恰大好处,具体做大如下:

首先,定义IsModified接口,此接口表示对象是否被修改 

 

package  ch7.Introduction;

public   interface  IsModified  {
  
public boolean isModified();
}

 

BeanOne.java

 

package  ch7.Introduction;

public   class  BeanOne  {
   
private String name;

public String getName() {
    
return name;
}


public void setName(String name) {
    
this.name = name;
}

}

混合体实现了IsModified接口,继承了DelegatingIntroductionInterceptor

 

package  ch7.Introduction;

import  java.lang.reflect.Method;
import  java.util.HashMap;
import  java.util.Map;

import  org.aopalliance.intercept.MethodInvocation;
import  org.springframework.aop.support.DelegatingIntroductionInterceptor;

public   class  IsModifiedMixin  extends  DelegatingIntroductionInterceptor
        
implements  IsModified  {
    
private boolean isModified=false;
    
private Map methodCache=new HashMap();    
    
public boolean isModified() {    
        
return isModified;
    }


    
public Object invoke(MethodInvocation invocation) throws Throwable {
        
if(!isModified){
           
if(invocation.getMethod().getName().startsWith("set")&&(invocation.getArguments().length==1))
           
{
               
//执行相应的getter方法判断是否真正的通过set方法修改了成员变量
              Method getter=getGetter(invocation.getMethod());  
               
if(getter!=null){
                   Object newVal
=invocation.getArguments()[0];
                   Object oldVal
=getter.invoke(invocation.getThis(),null);
                   
if((newVal==null)&&(oldVal==null)){
                       isModified
=false;
                   }
else if((newVal==null)&&(oldVal!=null)){
                       isModified
=true;
                   }
else if((newVal!=null)&&(oldVal==null)){
                       isModified
=true;
                   }
else{
            
            
                       isModified
=!newVal.equals(oldVal);
                   }

               }

           }

        }

        
return super.invoke(invocation);
    }

    
    
//从缓存中读取get反射方法
    private Method getGetter(Method setter){
        Method getter
=null;
        getter
=(Method)methodCache.get(setter);
        
if(getter!=null){
            
return getter;
        }

        String getterName
=setter.getName().replaceFirst("set""get");
        
try {
            getter
=setter.getDeclaringClass().getMethod(getterName,null);
            
synchronized(methodCache){
                methodCache.put(setter, getter);
            }

            
return getter;
        }
 catch (SecurityException e) {

            e.printStackTrace();
            
return null;
        }
 catch (NoSuchMethodException e) {

            e.printStackTrace();
            
return null;
        }

        
        
    }


}

测试代码:

 

package  ch7.Introduction;

import  org.aopalliance.aop.Advice;
import  org.springframework.aop.Advisor;
import  org.springframework.aop.Pointcut;
import  org.springframework.aop.framework.ProxyFactory;
import  org.springframework.aop.support.ControlFlowPointcut;
import  org.springframework.aop.support.DefaultIntroductionAdvisor;
import  org.springframework.aop.support.DefaultPointcutAdvisor;

public   class  Test  {

    
/**
     * 
@param args
     
*/

    
public static void main(String[] args) {
         BeanOne one
=new BeanOne();
         one.setName(
"gaoxiang");
         BeanOne proxyOne;
    
         
        
         Advisor advisor
=new DefaultIntroductionAdvisor(new IsModifiedMixin());
         
         
//创建BeanOne代理
         ProxyFactory pf1=new ProxyFactory();
         pf1.addAdvisor(advisor);
         pf1.setTarget(one);
         pf1.setOptimize(
true);
        
         BeanOne proxy
=(BeanOne)pf1.getProxy();
         IsModified proxyInterface
=(IsModified)proxy;
         
         System.out.println(
"Is BeanOne?"+(proxy instanceof BeanOne));
         System.out.println(
"Is IsModified?"+(proxy instanceof IsModified));
         
         
//测试程序是否经过修改
         System.out.println("has bean IsModified?"+proxyInterface.isModified());
         proxy.setName(
"gaoxiang");
         System.out.println(
"has bean IsModified?"+proxyInterface.isModified());
         proxy.setName(
"yulihua");
         System.out.println(
"has bean IsModified?"+proxyInterface.isModified());
         
    }

    

}

结果:

Is BeanOne?true
Is IsModified?true
has bean IsModified?false
has bean IsModified?false
has bean IsModified?true

后记:

我们创建代理的时候,设置了Optimize标志为true,强制使用CGLIB代理,如果我们使用JDK代理,则代理的混合体将不是一个类的实例,也就是说,我们使用CGLIB代理,Is BeanOne和Is IsModifie都为true,如果使用JDK代理,则Is Bean就为false

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值