DefaultAdvisorAutoProxyCreator类在xml文件中的使用,只针对增强器有效,没有工厂
使用原因:在配置文件中我们往往需要给很多个目标对象设置代理对象,那么之前例子的方式就需要每个目标对象的代理对象都需要配置一套类似的标签
自动代理:可以用很少的配置为xml文件中的目标对象自动的生成对应的代理对象(根据目标对象的变量名拿到代理类对象)
没有了工厂类
<bean class=“org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator” />
AccountServiceImpl.java
public class AccountServiceImpl implements IAccountService{
private AccountDao accountDao;
private Account account;
@Override
public void bankAction() {
accountDao.withdraw(account, 100);
accountDao.deposit(account, 100);
}
public AccountDao getAccountDao() {
return accountDao;
}
public void setAccountDao(AccountDao accountDao) {
this.accountDao = accountDao;
}
public Account getAccount() {
return account;
}
public void setAccount(Account account) {
this.account = account;
}
}
自增一个新的测试类com.briup.aop.autoProxy.MyTest
public class MyTest {
public void findUser(long id) {
System.out.println("findUser方法执行了");
}
public void findStudent(long id) {
System.out.println("findStudent方法执行了");
}
public void findTeacher(long id) {
System.out.println("findTeacher方法执行了");
}
public void bankTest(long id) {
System.out.println("bankTest方法执行了");
}
}
xml文件,现在有两个类AccountServiceImpl的对象target、myTest的对象test已经被初始化了,共有方法bankAction、findUser、findStudent、findTeacher、bankTest,,选择哪些方法被代理
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.2.xsd">
<!-- 配置切面类 -->
<bean name="logger" class="com.briup.aop.aspect.MyLogger"></bean>
<!-- 配置前置通知 -->
<bean name="beforeAdvice" class="com.briup.aop.before.BeforeAdvice">
<!-- 注入切面类对象 -->
<property name="logger" ref="logger"></property>
</bean>
<!-- 配置目标对象 -->
<bean name="target" class="com.briup.aop.service.AccountServiceImpl">
<!-- 注入相关的类 -->
<property name="accountDao" ref="accountDao"></property>
<property name="account" ref="account"></property>
</bean>
<!-- 配置dao层对象和account对象,为了给service注入 -->
<bean name="accountDao" class="com.briup.aop.dao.AccountDaoImpl"></bean>
<bean name="account" class="com.briup.aop.pojo.Account">
<property name="id" value="1"></property>
<property name="name" value="tom"></property>
<property name="balance" value="2000"></property>
</bean>
<!-- 自动代理 新加的类测试:多个类中的方法同时被代理 -->
<bean name="test" class="com.briup.aop.autoProxy.MyTest"></bean>
<!-- 增强器 -->
<!--作用:筛选出要代理的方法 -->
<bean id="advisor" class="org.springframework.aop.support.RegexpMethodPointcutAdvisor">
<!-- 注入通知 -->
<property name="advice" ref="beforeAdvice"></property>
<property name="patterns">
<list>
<!-- 正则表达式 -->
<value>.*find.*</value>
<value>.*bank.*</value>
</list>
</property>
</bean>
<!-- 自动代理 -->
<bean class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator" />
</beans>
自动代理是根据目标对象,当成要获取的代理对象的名字,拿到代理对象的名字。。。所以是container.getBean(“target”)
测试:
container.getBean(“target”);
container.getBean(“test”);
// 自动代理会把当前xml中配置的所有的对象全代理了
// 注意:一定是在使用了advisor的基础上才能使用这个自动代理
@Test
public void aop_autoproxy() {
try {
String path = "com/briup/aop/autoProxy/autoProxy.xml";
ApplicationContext container = new ClassPathXmlApplicationContext(path);
//拿目标类的变量名当成要获取的代理名
IAccountService proxy=(IAccountService) container.getBean("target");
proxy.bankAction();
System.out.println("------------");
System.out.println(proxy.toString());
System.out.println("------------");
System.out.println(proxy.getClass());
//第二个类中的方法代理
com.briup.aop.autoProxy.MyTest t= (MyTest) container.getBean("test");
t.findUser(1);
t.findStudent(1);
t.findTeacher(1);
t.bankTest(1);
System.out.println(t.getClass());
} catch (Exception e) {
e.printStackTrace();
}
}
使用自动代理的时候需要注意的方面:
1.当前的配置里面"一定要有"一个advisor的配置
2.不需要向自动代理类中注入任何信息,就这一个配置
<bean class=“org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator” />
3.不管目标对象是否实现了一个或多接口,自动代理的方式都能够为它产生代理对象(CGLib的方式).
4.从spring容器中拿代理对象的时候,需要通过目标对象的名字来拿。
5.spring如何确定配置文件中哪个bean是作为目标对象:通过advisor中筛选的方法,如果这个bean中含有advisor中所配置的方法,则这个bean将来称为我们的目标对象进行代理;如果是没有实现接口的就采用CGLib,如果使用的是接口方式就使用jdk代理方式
特点:自动代理必须有增强器,而且如果想代理多个类,则必须在增强器中有对应要过滤的类中的方法,不需要写更多的增强器了
总结:不需要写多个增强器了,只需要写一个就行了,在此增强器里面有对应过滤类中的方法。