`
rentianchou
  • 浏览: 69657 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

spring aop 自动代理机制

阅读更多
我们一直使用ProxyFactoryBean来显式的创建AOP代理。但是在很多场合,这种方式将会使编写配置文件的工作量大大增加;由于要从ProxyFactoryBean获得代理对象,也会使应用和Spring之间的耦合度增加。下面介绍使用Spring提供的自动代理机制来解决这类问题。

1、使用BeanNameAutoProxyCreator

       Spring提供的BeanNameAutoProxyCreator类允许我们通过Bean的name属性来指定代理的Bean。它暴露了java.lang.String[]类型的beanNames和 interceptorNames属性。beanNames可以指定被代理的Bean名字列表,支持“*”通配符,例如“*DAO”表示所有名字以“DAO”结尾的Bean。interceptorNames指定通知(Advice)列表,或者通知者(Advisor)列表。

        下面通过一个例程来演示如何使用BeanNameAutoProxyCreator。在例子中,有两个Bean:TestBeanA和BeanB,并在TestMain类中的main方法中调用其MyMethod()方法。自动代理将会在方法调用前自动的执行配置的前置通知,输出提示信息。

新建一个名字为AOP_Test4.10的工程,添加Spring的IoC和AOP库后,新建一aop.test包,再分别创建两个类TestBeanA和BeanB,添加MyMethod()方法,代码如下:

代码   查看源代码copy to clipboard打印
/**  
 *   
 */  
package aop.test;   
/**  
 * @author zhangyong  
 *   
 */  
public class TestBeanA {   
     public void MyMethod() {   
          System.out.println(this.getClass().getName()   
                + ".MyMethod() is run!");   
     }   
}   
/**
 * 
 */
package aop.test;
/**
 * @author zhangyong
 * 
 */
public class TestBeanA {
     public void MyMethod() {
          System.out.println(this.getClass().getName()
                + ".MyMethod() is run!");
     }
}



代码   查看源代码copy to clipboard打印
/**  
 *   
 */  
package aop.test;     
/**  
 * @author zhangyong  
 *   
 */  
public class BeanB {       
    public void MyMethod() {   
         System.out.println(this.getClass().getName()   
                 + ".MyMethod() is run!");   
    }   
}   
/**
 * 
 */
package aop.test;  
/**
 * @author zhangyong
 * 
 */
public class BeanB {    
    public void MyMethod() {
         System.out.println(this.getClass().getName()
                 + ".MyMethod() is run!");
    }
}

  再创建前置通知类BeforeAdvice:

代码   查看源代码copy to clipboard打印
/**  
 *   
 */  
package aop.test;     
import java.lang.reflect.Method;   
import org.springframework.aop.MethodBeforeAdvice;     
/**  
 * @author zhangyong  
 *   
 */  
public class BeforeAdvice implements MethodBeforeAdvice {     
     public void before(Method method, Object[] args, Object target)   
             throws Throwable {   
         System.out.println(method.getName() + "(),将要运行!");   
     }   
}   
/**
 * 
 */
package aop.test;  
import java.lang.reflect.Method;
import org.springframework.aop.MethodBeforeAdvice;  
/**
 * @author zhangyong
 * 
 */
public class BeforeAdvice implements MethodBeforeAdvice {  
     public void before(Method method, Object[] args, Object target)
             throws Throwable {
         System.out.println(method.getName() + "(),将要运行!");
     }
}
 
  最后创建含有main方法的测试类TestMain:

代码   查看源代码copy to clipboard打印
/**  
 *   
 */  
package aop.test;   
    
import org.springframework.context.ApplicationContext;   
import org.springframework.context.support.ClassPathXmlApplicationContext;     
/**  
 * @author zhangyong  
 *   
 */  
public class TestMain {    
     public static void main(String[] args) {   
         ApplicationContext ac = new ClassPathXmlApplicationContext(   
                 "applicationContext.xml");           
         TestBeanA beanA = (TestBeanA)ac.getBean("TestBeanA");   
         beanA.MyMethod();   
         BeanB beanB = (BeanB)ac.getBean("BeanB");   
         beanB.MyMethod();           
     }   
 }   
/**
 * 
 */
package aop.test;
 
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;  
/**
 * @author zhangyong
 * 
 */
public class TestMain { 
     public static void main(String[] args) {
         ApplicationContext ac = new ClassPathXmlApplicationContext(
                 "applicationContext.xml");        
         TestBeanA beanA = (TestBeanA)ac.getBean("TestBeanA");
         beanA.MyMethod();
         BeanB beanB = (BeanB)ac.getBean("BeanB");
         beanB.MyMethod();        
     }
 }

  在配置文件中配置Bean和自动代理Bean,完成后代码如下:

代码   查看源代码copy to clipboard打印
<?xml version="1.0" encoding="UTF-8"?>  
<beans …………>    
     <bean id="TestBeanA" class="aop.test.TestBeanA"/>  
     <bean id="BeanB" class="aop.test.BeanB"/>     
     <bean id="BeforeAdvice" class="aop.test.BeforeAdvice"></bean>  
     
     <bean class="org.springframework.aop.framework.autoproxy.   
                       BeanNameAutoProxyCreator">  
         <property name="beanNames">  
             <list>  
                 <value>Test*</value>  
             </list>  
         </property>  
         <property name="interceptorNames">  
             <list>  
                 <value>BeforeAdvice</value>  
             </list>  
         </property>  
     </bean>  
 </beans>  
<?xml version="1.0" encoding="UTF-8"?>
<beans …………> 
     <bean id="TestBeanA" class="aop.test.TestBeanA"/>
     <bean id="BeanB" class="aop.test.BeanB"/>  
     <bean id="BeforeAdvice" class="aop.test.BeforeAdvice"></bean>
  
     <bean class="org.springframework.aop.framework.autoproxy.
                       BeanNameAutoProxyCreator">
         <property name="beanNames">
             <list>
                 <value>Test*</value>
             </list>
         </property>
         <property name="interceptorNames">
             <list>
                 <value>BeforeAdvice</value>
             </list>
         </property>
     </bean>
 </beans>

  运行主类,输出结果如下:



  可以看到,在主类TestMain中,我们是直接从Spring IoC容器中获取收管Bean而不是像以前那样从ProxyFactoryBean中获取代理,但是我们的前置通知BeforeAdvice仍然在TestBeanA对象的MyMethod()方法执行前被触发,这说明我们的自动代理正在工作。

 

2、使用DefaultAdvisorAutoProxyCreator

  DefaultAdvisorAutoProxyCreator允许我们只需定义相应的Advisor通知者,就可以完成自动代理。配置好DefaultAdvisorAutoProxyCreator受管Bean后,它会自动查找配置文件中定义的Advisor,并将它们作用于所有的Bean。

修改例程4.10的配置文件,使用DefaultAdvisorAutoProxyCreator来完成自动代理。完成后配置文件代码如下(本例完整工程代码见例程4.11):

代码   查看源代码copy to clipboard打印
<?xml version="1.0" encoding="UTF-8"?>  
<beans ……>  
     <bean id="TestBeanA" class="aop.test.TestBeanA" />  
     <bean id="BeanB" class="aop.test.BeanB" />  
     <bean id="BeforeAdvice" class="aop.test.BeforeAdvice"/>  
     <bean class="org.springframework.aop.framework.autoproxy.   
                   DefaultAdvisorAutoProxyCreator" />  
     
    <bean class="org.springframework.aop.support.NameMatchMethod   
                                          PointcutAdvisor">  
         <property name="advice" ref="BeforeAdvice" />  
         <property name="mappedNames">  
             <list>  
                 <value>*Method*</value>  
             </list>  
         </property>  
     </bean>       
 </beans>  
<?xml version="1.0" encoding="UTF-8"?>
<beans ……>
     <bean id="TestBeanA" class="aop.test.TestBeanA" />
     <bean id="BeanB" class="aop.test.BeanB" />
     <bean id="BeforeAdvice" class="aop.test.BeforeAdvice"/>
     <bean class="org.springframework.aop.framework.autoproxy.
                   DefaultAdvisorAutoProxyCreator" />
  
    <bean class="org.springframework.aop.support.NameMatchMethod
                                          PointcutAdvisor">
         <property name="advice" ref="BeforeAdvice" />
         <property name="mappedNames">
             <list>
                 <value>*Method*</value>
             </list>
         </property>
     </bean>    
 </beans>

  运行主类输出结果如下:

分享到:
评论

相关推荐

    Spring AOP实现机制

    **Spring AOP 实现机制详解** Spring AOP(面向切面编程)是Spring框架的核心特性之一,它允许程序员在不修改源代码的情况下,通过“切面”来插入额外的业务逻辑,如日志、事务管理等。AOP的引入极大地提高了代码的...

    springAop默认代理方式.zip

    当目标对象实现了至少一个接口时,Spring将使用JDK的动态代理机制。JDK动态代理通过实现InvocationHandler接口,并在运行时动态生成一个实现了目标对象所有接口的代理类。 - **JDK动态代理**:JDK的java.lang....

    spring之AOP(动态代理)

    然而,如果需要更精细的控制,可以通过`@EnableAspectJAutoProxy`注解开启基于AspectJ的自动代理支持,或者通过`proxyTargetClass`属性来强制使用CGLIB代理。 总结一下,Spring的AOP机制通过JDK动态代理和CGLIB动态...

    springAOP配置动态代理实现

    综上所述,通过理解Spring AOP的配置和动态代理机制,我们可以灵活地在项目中添加横切关注点,提升代码的模块化和可维护性。在实际开发中,结合使用XML配置、注解配置以及适当的动态代理策略,可以使AOP功能更好地...

    spring AOP代理机制.docx

    总之,Spring AOP通过代理机制和通知机制,为开发者提供了一种优雅的方式,来处理那些横切关注点,提高了代码的复用性和模块化,降低了系统复杂性,使得业务逻辑更加清晰,提高了开发效率。无论是静态代理还是动态...

    Java动态代理(Spring Aop原理)

    动态代理提供了创建代理对象的机制,而Spring AOP则是基于动态代理实现的面向切面编程框架,简化了在多处插入相同逻辑的复杂度。在实际开发中,理解并熟练运用这两个技术对于提高代码质量和可维护性至关重要。

    spring AOP依赖三个jar包

    - **自动代理生成**:Spring容器可以在启动时自动识别并生成代理对象,无需手动创建。 - **事务管理**:Spring AOP的一个常见应用就是声明式事务管理,通过`@Transactional`注解可以轻松地在方法级别控制事务。 综...

    JDK动态代理 spring aop 的原理

    通过这个代理对象调用方法,Spring会自动插入预先定义好的通知逻辑。 总的来说,JDK动态代理是Spring AOP实现的基础,它允许我们在运行时动态创建代理对象,实现对方法调用的拦截和增强。Spring AOP则在此基础上...

    spring aop spring aop

    5. **代理(Proxy)**:Spring AOP通过动态代理机制创建目标对象的代理,代理对象在调用目标方法时会自动插入切面逻辑。在Java项目中,Spring可以使用JDK动态代理或CGLIB动态代理来创建代理对象。 在实际应用中,...

    SpringAOP之探秘(动态代理、责任链模式、注解使用)

    CGLIB通常作为Spring AOP的默认代理机制,因为它可以处理未实现接口的类。 接下来,我们来探讨责任链模式。在Spring AOP中,每个切面(Aspect)都可以看作是责任链上的一个节点。当一个方法被调用时,这个调用会...

    SPRING AOP详细培训视频

    4. 使用注解驱动的AOP配置,以及如何在Spring配置文件中启用AOP自动代理。 5. 引入的概念和使用,以及如何通过引入增加类的方法或属性。 6. 实践示例,可能包括事务管理、日志记录等实际应用场景的AOP实现。 通过这...

    Spring AOP的底层实现技术

    Spring AOP基于两种代理机制实现:JDK动态代理和CGLIB代理。JDK动态代理适用于实现了接口的目标对象,通过反射机制创建一个代理类来拦截方法调用。而CGLIB是在运行时动态生成一个目标类的子类,从而实现对方法的...

    springAOP之代理模式.docx

    Spring AOP在默认情况下使用JDK动态代理,但当目标类没有接口时,会自动切换到CGLib。通过动态代理,Spring可以在运行时创建代理对象,根据配置织入相应的切面逻辑,无需程序员手动创建和维护代理类。 总的来说,...

    spring aop 依赖jar

    或者,在Spring Boot项目中,由于自动配置,通常不需要显式配置AOP代理。 总的来说,理解并正确配置Spring AOP的依赖,以及熟练掌握切面、通知和切入点的概念,对于有效利用Spring进行面向切面编程至关重要。通过...

    Spring AOP学习资料(pdf)

    通过本资料的学习,我们了解到Spring AOP是一种强大的工具,它通过代理机制有效地分离了业务逻辑与系统需求,极大地提升了系统的可维护性和扩展性。掌握Spring AOP的基本概念和实现方法对于开发高效、健壮的企业级...

    spring aop4.3.10

    6. **自动代理(Auto-proxy)**:Spring提供自动代理机制,可以通过配置或注解来自动识别哪些bean应该被代理。`@EnableAspectJAutoProxy`注解可以开启基于AspectJ的自动代理。 7. **注解驱动的AOP**:从Spring 2.5...

    springAOP核心组件分析.pdf

    Spring AOP(面向切面编程)是Spring框架的一个重要组成部分,它允许开发者将...开发者无需手动编写代理类,Spring的AOP框架自动识别和应用配置中的AOP规则,大大简化了AOP的应用,并提高了代码的可维护性和可扩展性。

    spring-aop.rar_aop1270_spring_spring aop

    二、Spring AOP实现机制 Spring AOP通过动态代理来实现,主要有两种代理方式: 1. JDK动态代理:适用于实现了接口的目标对象,通过反射创建代理对象,代理对象在调用真实对象方法前/后执行通知。 2. CGLIB代理:...

    spring aop代理列子

    package com.gc.autoproxy下为:aop方式自动代理 package com.gc.cglib下为:aop方式cglib代理 package com.gc.dynproxy下为:aop方式动态代理 package com.gc.javaproxy下为:java代理机制实现 package ...

    spring Aop文档

    2. **`ProxyFactoryBean`**:Spring AOP的主要代理工厂,用于创建JDK动态代理。 3. **`CglibAopProxy`**:使用CGLIB库创建代理对象,适用于无法使用JDK动态代理的情况(如目标对象未实现接口)。 #### 六、Spring ...

Global site tag (gtag.js) - Google Analytics