我们一直使用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>
运行主类输出结果如下:
分享到:
相关推荐
package com.gc.autoproxy下为:aop方式自动代理 package com.gc.cglib下为:aop方式cglib代理 package com.gc.dynproxy下为:aop方式动态代理 package com.gc.javaproxy下为:java代理机制实现 package ...
Spring AOP多种代理机制相关核心类介绍先介绍一些Spring Aop中一些核心类,大致分为三类: advisorCreator ,从spring ioc的扩展接口beanPostProcessor继承,主要用作扫描获取advisor。 advisor :顾问的意思,封装...
再细问:如果循环依赖的时候,所有类又都需要Spring AOP自动代理,那Spring如何提前曝光?曝光的是原始bean还是代理后的bean? 这些问题算是Spring源码的压轴题了,如果这些问题都弄明白,恭喜你顺利结业Spring源码...
Spring的AOP的底层实现原理; 为什么jdk动态代理是必须是接口 两种动态代理的区别 AOP实现方式:aop注解或者xml配置;后来工具jar包aspects; aop的属性 事务 事务编码方式: 事务注意事项; 为什么同一个类A调用b...
6.6. 代理机制 6.7. 编程方式创建@AspectJ代理 6.8. 在Spring应用中使用AspectJ 6.8.1. 在Spring中使用AspectJ来为domain object进行依赖注入 6.8.2. Spring中其他的AspectJ切面 6.8.3. 使用Spring IoC来配置...
Nepxion Matrix是一种集成的Spring AutoProxy,Spring Registrar和Spring Import Selector三种机制的AOP框架,具有很高的通用性,健壮性,可选和易用性请联系我微信,钉钉,公众号和文档简介Spring自动代理机制它...
6.6. 代理机制 6.7. 编程方式创建@AspectJ代理 6.8. 在Spring应用中使用AspectJ 6.8.1. 在Spring中使用AspectJ来为domain object进行依赖注入 6.8.1.1. @Configurable object的单元测试 6.8.1.2. 多application ...
6.6. 代理机制 6.6.1. 理解AOP代理 6.7. 以编程方式创建@AspectJ代理 6.8. 在Spring应用中使用AspectJ 6.8.1. 在Spring中使用AspectJ进行domain object的依赖注入 6.8.2. Spring中其他的AspectJ切面 6.8.3. ...
6.6. 代理机制 6.7. 编程方式创建@AspectJ代理 6.8. 在Spring应用中使用AspectJ 6.8.1. 在Spring中使用AspectJ来为domain object进行依赖注入 6.8.2. Spring中其他的AspectJ切面 6.8.3. 使用Spring IoC来配置...
6.6. 代理机制 6.6.1. 理解AOP代理 6.7. 以编程方式创建@AspectJ代理 6.8. 在Spring应用中使用AspectJ 6.8.1. 在Spring中使用AspectJ进行domain object的依赖注入 6.8.2. Spring中其他的AspectJ切面 6.8.3. ...
从代理机制初探 AOP 动态代理 <br>AOP 观念与术语 Spring AOP Advices Advices 包括了Aspect 的真正逻辑,由于缝合至Targets的时机不同,Spring 提供了几种不同的 Advices。 Before ...
springboot Spring框架是Java平台上的一种开源应用框架,提供具有控制反转...Spring框架具有面向切面编程(AOP)框架,SpringAOP框架基于代理模式,同时运行时可配置;AOP框架主要针对模块之间的交叉关注点进行模块化。
springboot Spring框架是Java平台上的一种开源应用框架,提供具有控制反转...Spring框架具有面向切面编程(AOP)框架,SpringAOP框架基于代理模式,同时运行时可配置;AOP框架主要针对模块之间的交叉关注点进行模块化。
10.6.1 哪些方法不能实施Spring AOP事务 10.6.2 事务增强遗漏实例 10.7 数据连接泄漏 10.7.1 底层连接资源的访问问题 10.7.2 Spring JDBC数据连接泄漏 10.7.3 通过DataSourceUtils获取数据连接 10.7.4 通过...
10.6.1 哪些方法不能实施Spring AOP事务 10.6.2 事务增强遗漏实例 10.7 数据连接泄漏 10.7.1 底层连接资源的访问问题 10.7.2 Spring JDBC数据连接泄漏 10.7.3 通过DataSourceUtils获取数据连接 10.7.4 通过...
37.5.1自动令牌包含 271 37.5.2解析CsrfToken 272 第七部分 Spring数据集成 273 38. Spring Data&Spring安全配置 273 39. @Query中的安全表达式 273 第八部分 附录 274 40.安全数据库模式 274 40.1用户模式 274 ...
8.4.1 Spring 的事务机制 297 8.4.2 声名式事务 298 8.4.3 注解事务行为 299 8.4.4 类级别使用@Transactional 300 8.4.5 Spring Data JPA 的事务支持 300 8.4.6 Spring Boot 的事务支持 302 8.4.7 实战 303 8.5 数据...
8.4.1 Spring 的事务机制 297 8.4.2 声名式事务 298 8.4.3 注解事务行为 299 8.4.4 类级别使用@Transactional 300 8.4.5 Spring Data JPA 的事务支持 300 8.4.6 Spring Boot 的事务支持 302 8.4.7 实战 303 8.5 数据...
8.4.1 Spring 的事务机制 297 8.4.2 声名式事务 298 8.4.3 注解事务行为 299 8.4.4 类级别使用@Transactional 300 8.4.5 Spring Data JPA 的事务支持 300 8.4.6 Spring Boot 的事务支持 302 8.4.7 实战 303 8.5 数据...
spring使用AOP面向切面的思想进行事务管理的。 spring和Hibernate继承后,定义事务管理特性的时候查询为什么要定义为read-only? 答:因为添加、删除和更新都涉及到了数据库的修改,而查询并未涉及到数据库修改,...