使用BeanNameAutoProxyCreator实现spring的自动代理

时间:2023-03-08 17:52:07
使用BeanNameAutoProxyCreator实现spring的自动代理

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

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

业务接口

使用BeanNameAutoProxyCreator实现spring的自动代理package AutoProxyOne;
使用BeanNameAutoProxyCreator实现spring的自动代理
使用BeanNameAutoProxyCreator实现spring的自动代理public interface Shopping {
使用BeanNameAutoProxyCreator实现spring的自动代理  public String buySomething(String type);
使用BeanNameAutoProxyCreator实现spring的自动代理  public String buyAnything(String type);
使用BeanNameAutoProxyCreator实现spring的自动代理  public String sellSomething(String type);
使用BeanNameAutoProxyCreator实现spring的自动代理  public String sellAnything(String type);
使用BeanNameAutoProxyCreator实现spring的自动代理
使用BeanNameAutoProxyCreator实现spring的自动代理
使用BeanNameAutoProxyCreator实现spring的自动代理}
使用BeanNameAutoProxyCreator实现spring的自动代理

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

使用BeanNameAutoProxyCreator实现spring的自动代理package AutoProxyOne;
使用BeanNameAutoProxyCreator实现spring的自动代理
使用BeanNameAutoProxyCreator实现spring的自动代理public class ShoppingImplA implements Shopping {
使用BeanNameAutoProxyCreator实现spring的自动代理    private Customer customer;
使用BeanNameAutoProxyCreator实现spring的自动代理    public Customer getCustomer() {
使用BeanNameAutoProxyCreator实现spring的自动代理        return customer;
使用BeanNameAutoProxyCreator实现spring的自动代理    }
使用BeanNameAutoProxyCreator实现spring的自动代理    public void setCustomer(Customer customer) {
使用BeanNameAutoProxyCreator实现spring的自动代理        this.customer = customer;
使用BeanNameAutoProxyCreator实现spring的自动代理    }
使用BeanNameAutoProxyCreator实现spring的自动代理    public String buySomething(String type) {
使用BeanNameAutoProxyCreator实现spring的自动代理        System.out.println(this.getCustomer().getName()+" bye "+type+" success");
使用BeanNameAutoProxyCreator实现spring的自动代理        return null;
使用BeanNameAutoProxyCreator实现spring的自动代理    }
使用BeanNameAutoProxyCreator实现spring的自动代理    
使用BeanNameAutoProxyCreator实现spring的自动代理    public String buyAnything(String type) {
使用BeanNameAutoProxyCreator实现spring的自动代理       System.out.println(this.getCustomer().getName()+" bye "+type+" success");
使用BeanNameAutoProxyCreator实现spring的自动代理       return null;
使用BeanNameAutoProxyCreator实现spring的自动代理
使用BeanNameAutoProxyCreator实现spring的自动代理     }
使用BeanNameAutoProxyCreator实现spring的自动代理    public String sellAnything(String type) {
使用BeanNameAutoProxyCreator实现spring的自动代理        System.out.println(this.getCustomer().getName()+" sell "+type+" success");
使用BeanNameAutoProxyCreator实现spring的自动代理        return null;
使用BeanNameAutoProxyCreator实现spring的自动代理    }
使用BeanNameAutoProxyCreator实现spring的自动代理    public String sellSomething(String type) {
使用BeanNameAutoProxyCreator实现spring的自动代理         System.out.println(this.getCustomer().getName()+" sell "+type+" success");
使用BeanNameAutoProxyCreator实现spring的自动代理           return null;
使用BeanNameAutoProxyCreator实现spring的自动代理    }
使用BeanNameAutoProxyCreator实现spring的自动代理
使用BeanNameAutoProxyCreator实现spring的自动代理}
使用BeanNameAutoProxyCreator实现spring的自动代理

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

使用BeanNameAutoProxyCreator实现spring的自动代理package AutoProxyOne;
使用BeanNameAutoProxyCreator实现spring的自动代理
使用BeanNameAutoProxyCreator实现spring的自动代理public class ShoppingImplB implements Shopping {
使用BeanNameAutoProxyCreator实现spring的自动代理    private Customer customer;
使用BeanNameAutoProxyCreator实现spring的自动代理    public Customer getCustomer() {
使用BeanNameAutoProxyCreator实现spring的自动代理        return customer;
使用BeanNameAutoProxyCreator实现spring的自动代理    }
使用BeanNameAutoProxyCreator实现spring的自动代理    public void setCustomer(Customer customer) {
使用BeanNameAutoProxyCreator实现spring的自动代理        this.customer = customer;
使用BeanNameAutoProxyCreator实现spring的自动代理    }
使用BeanNameAutoProxyCreator实现spring的自动代理    public String buySomething(String type) {
使用BeanNameAutoProxyCreator实现spring的自动代理        System.out.println(this.getCustomer().getName()+" bye "+type+" success");
使用BeanNameAutoProxyCreator实现spring的自动代理        return null;
使用BeanNameAutoProxyCreator实现spring的自动代理    }
使用BeanNameAutoProxyCreator实现spring的自动代理    
使用BeanNameAutoProxyCreator实现spring的自动代理    public String buyAnything(String type) {
使用BeanNameAutoProxyCreator实现spring的自动代理       System.out.println(this.getCustomer().getName()+" bye "+type+" success");
使用BeanNameAutoProxyCreator实现spring的自动代理       return null;
使用BeanNameAutoProxyCreator实现spring的自动代理
使用BeanNameAutoProxyCreator实现spring的自动代理     }
使用BeanNameAutoProxyCreator实现spring的自动代理    public String sellAnything(String type) {
使用BeanNameAutoProxyCreator实现spring的自动代理        System.out.println(this.getCustomer().getName()+" sell "+type+" success");
使用BeanNameAutoProxyCreator实现spring的自动代理        return null;
使用BeanNameAutoProxyCreator实现spring的自动代理    }
使用BeanNameAutoProxyCreator实现spring的自动代理    public String sellSomething(String type) {
使用BeanNameAutoProxyCreator实现spring的自动代理         System.out.println(this.getCustomer().getName()+" sell "+type+" success");
使用BeanNameAutoProxyCreator实现spring的自动代理           return null;
使用BeanNameAutoProxyCreator实现spring的自动代理    }
使用BeanNameAutoProxyCreator实现spring的自动代理
使用BeanNameAutoProxyCreator实现spring的自动代理}
使用BeanNameAutoProxyCreator实现spring的自动代理

切面通知:

使用BeanNameAutoProxyCreator实现spring的自动代理package AutoProxyOne;
使用BeanNameAutoProxyCreator实现spring的自动代理
使用BeanNameAutoProxyCreator实现spring的自动代理import java.lang.reflect.Method;
使用BeanNameAutoProxyCreator实现spring的自动代理
使用BeanNameAutoProxyCreator实现spring的自动代理import org.springframework.aop.MethodBeforeAdvice;
使用BeanNameAutoProxyCreator实现spring的自动代理//前置通知
使用BeanNameAutoProxyCreator实现spring的自动代理public class WelcomeAdvice implements MethodBeforeAdvice {
使用BeanNameAutoProxyCreator实现spring的自动代理
使用BeanNameAutoProxyCreator实现spring的自动代理    public void before(Method method, Object[] args, Object obj)
使用BeanNameAutoProxyCreator实现spring的自动代理            throws Throwable {
使用BeanNameAutoProxyCreator实现spring的自动代理        
使用BeanNameAutoProxyCreator实现spring的自动代理        System.out.println("Hello welcome to bye ");
使用BeanNameAutoProxyCreator实现spring的自动代理
使用BeanNameAutoProxyCreator实现spring的自动代理    }
使用BeanNameAutoProxyCreator实现spring的自动代理
使用BeanNameAutoProxyCreator实现spring的自动代理}
使用BeanNameAutoProxyCreator实现spring的自动代理

配置文件:

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

使用BeanNameAutoProxyCreator实现spring的自动代理<?xml version="1.0" encoding="UTF-8"?>
使用BeanNameAutoProxyCreator实现spring的自动代理<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd" >
使用BeanNameAutoProxyCreator实现spring的自动代理<beans>
使用BeanNameAutoProxyCreator实现spring的自动代理 <bean id="WelcomeAdvice" class="AutoProxyOne.WelcomeAdvice">
使用BeanNameAutoProxyCreator实现spring的自动代理 </bean>
使用BeanNameAutoProxyCreator实现spring的自动代理 
使用BeanNameAutoProxyCreator实现spring的自动代理 <bean  class="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator">
使用BeanNameAutoProxyCreator实现spring的自动代理   <property name="beanNames">
使用BeanNameAutoProxyCreator实现spring的自动代理     <list>
使用BeanNameAutoProxyCreator实现spring的自动代理       <value>buy*</value>
使用BeanNameAutoProxyCreator实现spring的自动代理     </list>
使用BeanNameAutoProxyCreator实现spring的自动代理   </property>
使用BeanNameAutoProxyCreator实现spring的自动代理   <property name="interceptorNames">
使用BeanNameAutoProxyCreator实现spring的自动代理     <list>
使用BeanNameAutoProxyCreator实现spring的自动代理        <value>WelcomeAdvice</value>
使用BeanNameAutoProxyCreator实现spring的自动代理     </list> 
使用BeanNameAutoProxyCreator实现spring的自动代理   </property>
使用BeanNameAutoProxyCreator实现spring的自动代理
使用BeanNameAutoProxyCreator实现spring的自动代理 </bean>
使用BeanNameAutoProxyCreator实现spring的自动代理   
使用BeanNameAutoProxyCreator实现spring的自动代理  <bean id="buyBean" class="AutoProxyOne.ShoppingImplA">
使用BeanNameAutoProxyCreator实现spring的自动代理    <property name="customer">
使用BeanNameAutoProxyCreator实现spring的自动代理      <ref bean="customer"/>
使用BeanNameAutoProxyCreator实现spring的自动代理    </property>
使用BeanNameAutoProxyCreator实现spring的自动代理   </bean>
使用BeanNameAutoProxyCreator实现spring的自动代理 <bean id="sellBean" class="AutoProxyOne.ShoppingImplB">
使用BeanNameAutoProxyCreator实现spring的自动代理    <property name="customer">
使用BeanNameAutoProxyCreator实现spring的自动代理      <ref bean="customer"/>
使用BeanNameAutoProxyCreator实现spring的自动代理    </property>
使用BeanNameAutoProxyCreator实现spring的自动代理   </bean>
使用BeanNameAutoProxyCreator实现spring的自动代理
使用BeanNameAutoProxyCreator实现spring的自动代理
使用BeanNameAutoProxyCreator实现spring的自动代理<bean id="customer" class="AutoProxyOne.Customer">
使用BeanNameAutoProxyCreator实现spring的自动代理   <constructor-arg index="0">
使用BeanNameAutoProxyCreator实现spring的自动代理     <value>gaoxiang</value>
使用BeanNameAutoProxyCreator实现spring的自动代理   </constructor-arg>
使用BeanNameAutoProxyCreator实现spring的自动代理    <constructor-arg index="1">
使用BeanNameAutoProxyCreator实现spring的自动代理     <value>26</value>
使用BeanNameAutoProxyCreator实现spring的自动代理   </constructor-arg>
使用BeanNameAutoProxyCreator实现spring的自动代理 </bean>
使用BeanNameAutoProxyCreator实现spring的自动代理
使用BeanNameAutoProxyCreator实现spring的自动代理
使用BeanNameAutoProxyCreator实现spring的自动代理</beans>
使用BeanNameAutoProxyCreator实现spring的自动代理
使用BeanNameAutoProxyCreator实现spring的自动代理

测试代码:

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

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

ApplicationContext ctx=new FileSystemXmlApplicationContext(filePath);

而不能用

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

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

使用BeanNameAutoProxyCreator实现spring的自动代理package AutoProxyOne;
使用BeanNameAutoProxyCreator实现spring的自动代理
使用BeanNameAutoProxyCreator实现spring的自动代理import java.io.File;
使用BeanNameAutoProxyCreator实现spring的自动代理
使用BeanNameAutoProxyCreator实现spring的自动代理import org.springframework.beans.factory.BeanFactory;
使用BeanNameAutoProxyCreator实现spring的自动代理import org.springframework.beans.factory.xml.XmlBeanFactory;
使用BeanNameAutoProxyCreator实现spring的自动代理import org.springframework.context.ApplicationContext;
使用BeanNameAutoProxyCreator实现spring的自动代理import org.springframework.context.support.FileSystemXmlApplicationContext;
使用BeanNameAutoProxyCreator实现spring的自动代理import org.springframework.core.io.FileSystemResource;
使用BeanNameAutoProxyCreator实现spring的自动代理
使用BeanNameAutoProxyCreator实现spring的自动代理
使用BeanNameAutoProxyCreator实现spring的自动代理import org.springframework.aop.support.RegexpMethodPointcutAdvisor;
使用BeanNameAutoProxyCreator实现spring的自动代理public class TestAdvisor {
使用BeanNameAutoProxyCreator实现spring的自动代理
使用BeanNameAutoProxyCreator实现spring的自动代理    public static void main(String[] args) {
使用BeanNameAutoProxyCreator实现spring的自动代理
使用BeanNameAutoProxyCreator实现spring的自动代理        String filePath=System.getProperty("user.dir")+File.separator+"AutoProxyOne"+File.separator+"hello.xml";
使用BeanNameAutoProxyCreator实现spring的自动代理        
使用BeanNameAutoProxyCreator实现spring的自动代理        BeanFactory factory=new XmlBeanFactory(new FileSystemResource(filePath));
使用BeanNameAutoProxyCreator实现spring的自动代理        ApplicationContext ctx=new FileSystemXmlA