使用BeanNameAutoProxyCreator实现spring的自动代理

提到代理,我们可以使用ProxyBeanFactory,并配置proxyInterfaces,target和interceptorNames实现,但如果需要代理的bean很多,无疑会对spring配置文件的编写带来繁重的工作

Spring为我们提供了,根据beanName匹配后进行自动代理的解决方法

业务接口

 

package  AutoProxyOne;

public   interface  Shopping  {
  
public String buySomething(String type);
  
public String buyAnything(String type);
  
public String sellSomething(String type);
  
public String sellAnything(String type);


}

 业务实现类A,作为配置文件中的buyBean:

 

package  AutoProxyOne;

public   class  ShoppingImplA  implements  Shopping  {
    
private Customer customer;
    
public Customer getCustomer() {
        
return customer;
    }

    
public void setCustomer(Customer customer) {
        
this.customer = customer;
    }

    
public String buySomething(String type) {
        System.out.println(
this.getCustomer().getName()+" bye "+type+" success");
        
return null;
    }

    
    
public String buyAnything(String type) {
       System.out.println(
this.getCustomer().getName()+" bye "+type+" success");
       
return null;

     }

    
public String sellAnything(String type) {
        System.out.println(
this.getCustomer().getName()+" sell "+type+" success");
        
return null;
    }

    
public String sellSomething(String type) {
         System.out.println(
this.getCustomer().getName()+" sell "+type+" success");
           
return null;
    }


}

 

 业务实现类B,作为配置文件中的sellBean:

 

package  AutoProxyOne;

public   class  ShoppingImplB  implements  Shopping  {
    
private Customer customer;
    
public Customer getCustomer() {
        
return customer;
    }

    
public void setCustomer(Customer customer) {
        
this.customer = customer;
    }

    
public String buySomething(String type) {
        System.out.println(
this.getCustomer().getName()+" bye "+type+" success");
        
return null;
    }

    
    
public String buyAnything(String type) {
       System.out.println(
this.getCustomer().getName()+" bye "+type+" success");
       
return null;

     }

    
public String sellAnything(String type) {
        System.out.println(
this.getCustomer().getName()+" sell "+type+" success");
        
return null;
    }

    
public String sellSomething(String type) {
         System.out.println(
this.getCustomer().getName()+" sell "+type+" success");
           
return null;
    }


}

 

切面通知:

 

package  AutoProxyOne;

import  java.lang.reflect.Method;

import  org.springframework.aop.MethodBeforeAdvice;
// 前置通知
public   class  WelcomeAdvice  implements  MethodBeforeAdvice  {

    
public void before(Method method, Object[] args, Object obj)
            
throws Throwable {
        
        System.out.println(
"Hello welcome to bye ");

    }


}

 

配置文件:

其中beanNames为buy*,意味着所有以buy开头的bean,都被spring容易自动代理,执行相应的切面通知

 

<? xml version="1.0" encoding="UTF-8" ?>
<! DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd"  >
< beans >
 
< bean  id ="WelcomeAdvice"  class ="AutoProxyOne.WelcomeAdvice" >
 
</ bean >
 
 
< bean   class ="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator" >
   
< property  name ="beanNames" >
     
< list >
       
< value > buy* </ value >
     
</ list >
   
</ property >
   
< property  name ="interceptorNames" >
     
< list >
        
< value > WelcomeAdvice </ value >
     
</ list >  
   
</ property >

 
</ bean >
   
  
< bean  id ="buyBean"  class ="AutoProxyOne.ShoppingImplA" >
    
< property  name ="customer" >
      
< ref  bean ="customer" />
    
</ property >
   
</ bean >
 
< bean  id ="sellBean"  class ="AutoProxyOne.ShoppingImplB" >
    
< property  name ="customer" >
      
< ref  bean ="customer" />
    
</ property >
   
</ bean >


< bean  id ="customer"  class ="AutoProxyOne.Customer" >
   
< constructor-arg  index ="0" >
     
< value > gaoxiang </ value >
   
</ constructor-arg >
    
< constructor-arg  index ="1" >
     
< value > 26 </ value >
   
</ constructor-arg >
 
</ bean >


</ beans >

 

测试代码:

在测试代码中,我们的buyBean打印两条买的信息,sellBean打印两条卖的信息,可以看到buyBean执行的方法已经进行了切面处理

需要注意的是,如果使用自动代码,则获得Spring Bean工厂要用

ApplicationContext ctx=new FileSystemXmlApplicationContext(filePath);

而不能用

BeanFactory factory=new XmlBeanFactory(new FileSystemResource(filePath));

原因我想是因为BeanFactory在初始化时并不实例化单例的Bean,而ApplicationContext则在初始化时候全部实例化了Bean,自动代理需要在初始化时候定义好代理关系

 

package  AutoProxyOne;

import  java.io.File;

import  org.springframework.beans.factory.BeanFactory;
import  org.springframework.beans.factory.xml.XmlBeanFactory;
import  org.springframework.context.ApplicationContext;
import  org.springframework.context.support.FileSystemXmlApplicationContext;
import  org.springframework.core.io.FileSystemResource;


import  org.springframework.aop.support.RegexpMethodPointcutAdvisor;
public   class  TestAdvisor  {

    
public static void main(String[] args) {

        String filePath
=System.getProperty("user.dir")+File.separator+"AutoProxyOne"+File.separator+"hello.xml";
        
        BeanFactory factory
=new XmlBeanFactory(new FileSystemResource(filePath));
        ApplicationContext ctx
=new FileSystemXmlApplicationContext(filePath);
        Shopping shoppingA
=null;
        Shopping shoppingB
=null;
        shoppingA
=(Shopping)ctx.getBean("buyBean");
        shoppingB
=(Shopping)ctx.getBean("sellBean");
        shoppingA.buySomething(
"something");
        shoppingA.buyAnything(
"anything");
        shoppingB.sellAnything(
"anything");
        shoppingB.sellSomething(
"something");
        
    

    }

}

 

运行结果:

Hello welcome to bye
gaoxiang bye something success
Hello welcome to bye
gaoxiang bye anything success
gaoxiang sell anything success
gaoxiang sell something success

 

可以看到,buyBean的方法都进行了切面处理,而sellBean的方法没有进行切面处理

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值