• 使用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 FileSystemXmlA
  • 相关阅读:
    jmeter笔记5
    jmeter笔记4
    jmeter笔记3
    jmeter笔记2
    jmeter笔记1
    robot API笔记4
    robotframework笔记27
    robotframework笔记25
    robotframework笔记26
    robotframework笔记24
  • 原文地址:https://www.cnblogs.com/langtianya/p/5138125.html
Copyright © 2020-2023  润新知