前面的文章中讲到的创建代理,在配置文件中都必须配置:ProxyFactoryBean。这虽然省掉了我们手动实现动态代理的工作,但是也很繁琐。
现在有三种解决方案:
1:BeanNameAutoProxyCreator:根据Bean名称创建代理
2:DefaultAdvisorAutoProxyCreator:根据Advisor本身包含信息创建代理。
3:AnnotationAwareAspectJAutoProxyCreator:基于Bean中的AspectJ注解进行自动代理。
现在我们先介绍前两种。
BeanNameAutoProxyCreator示例:
我们对所有以DAO 结尾的Bean的所有方法使用代理。
核心知识点:在配置文件中配置自动代理类BeanNameAutoProxyCreator。在使用中(比如测试类中),使用applicationContext.getBean(目标类Id)即可,已经被自动代理增强了。这就是自动的意义所在。
注意,BeanNameAutoProxyCreator这个类,只能按BeanName来筛选,具体的方法没法筛选,也就是使用了一般切面,不能指定切入点。
先创建一个StudentDao接口
package com.imooc.aop.demo5;
public interface StudentDao {
public void find();
public void save();
public void update();
public void delete();
}
创建其实现类StudentDaoImpl
package com.imooc.aop.demo5;
public class StudentDaoImpl implements StudentDao {
public void find() {
System.out.println("学生查询");
}
public void save() {
System.out.println("学生保存");
}
public void update() {
System.out.println("学生修改");
}
public void delete() {
System.out.println("学生删除");
}
}
在整一个CustomerDao类:
package com.imooc.aop.demo5;
public class CustomerDao {
public void find(){
System.out.println("查询客户");
}
public void save(){
System.out.println("保存客户");
}
public void update(){
System.out.println("修改客户");
}
public void delete(){
System.out.println("删除客户");
}
}
再来个增强处理类MyBeforeAdvice
package com.imooc.aop.demo5;
import org.springframework.aop.MethodBeforeAdvice;
import java.lang.reflect.Method;
public class MyBeforeAdvice implements MethodBeforeAdvice {
public void before(Method method, Object[] args, Object target) throws Throwable {
System.out.println("前置增强===================");
}
}
配置文件整好:applicationContext3.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<!--配置目标类-->
<bean id="studentDao" class="com.imooc.aop.demo5.StudentDaoImpl"></bean>
<bean id="customerDao" class="com.imooc.aop.demo5.CustomerDao"></bean>
<!--配置增强处理-->
<bean id="myBeforeAdvice" class="com.imooc.aop.demo5.MyBeforeAdvice"></bean>
<!--配置自动代理-->
<!--配置基于BeanNameAutoProxyCreator类的自动代理-->
<bean class="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator">
<!--配置作用于的bean,也就是筛选BeanName-->
<property name="beanNames" value="*Dao"></property>
<!--配置增强处理-->
<property name="interceptorNames" value="myBeforeAdvice"></property>
</bean>
</beans>
这就完成了,进行测试:
package com.imooc.aop.demo5;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class SpringDemo5 {
@Test
public void demo1(){
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext3.xml");
StudentDao studentDaoProxy = (StudentDao)applicationContext.getBean("studentDao");
CustomerDao customerDaoProxy = (CustomerDao)applicationContext.getBean("customerDao");
studentDaoProxy.delete();
studentDaoProxy.find();
customerDaoProxy.delete();
customerDaoProxy.find();
}
}
从运行结果可以看出,这两个类都被代理了,也被增强处理了。
DefaultAdvisorAutoProxyCreator
这个自动代理可以指定切面切入点。
和BeanNameAutoProxyCreator的区别就是配置文件中配置不同的自动代理类。增加切入点的配置。
这里对所有Bean的save方法都进行了增强。如果只作用与指定的Bean,可以在切面的pattern设置中修改value的值。
将配置文件修改为如下:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<!--配置目标类-->
<bean id="studentDao" class="com.imooc.aop.demo6.StudentDaoImpl"></bean>
<bean id="customerDao" class="com.imooc.aop.demo6.CustomerDao"></bean>
<!--配置增强处理-->
<bean id="myBeforeAdvice" class="com.imooc.aop.demo6.MyBeforeAdvice"></bean>
<!--配置切面-->
<bean id="myAdvisor" class="org.springframework.aop.support.RegexpMethodPointcutAdvisor">
//对切入点进行过滤,只用于save方法
<property name="pattern" value=".*save"></property>
<property name="advice" ref="myBeforeAdvice"></property>
</bean>
<!--基于切面信息来产生自动代理-->
<bean class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator"></bean>
</beans>
再进行测试:
package com.imooc.aop.demo5;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class SpringDemo5 {
@Test
public void demo1(){
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext3.xml");
StudentDao studentDaoProxy = (StudentDao)applicationContext.getBean("studentDao");
CustomerDao customerDaoProxy = (CustomerDao)applicationContext.getBean("customerDao");
studentDaoProxy.delete();
studentDaoProxy.save();
customerDaoProxy.delete();
customerDaoProxy.save();
}
}
从结果可以看出,两个对象被代理,且他们的save方法进行了增强。