Spring自动代理
Spring的一般代理是通过ProxyFactoryBean织入切面代理,如果有非常多的Dao则每个Dao都需要配置ProxyFeactoryBean开发维护非常麻烦
解决方案:自动创建代理
- BeanNameAutoProxyCreator根据Bean名称创建代理
- DefaultAdvisorAutoProxyCreator根据Advisor本身包含信息创建代理
- AnnotationAwareAspectJAutoProxyCreator基于Bean中的AspectJ注解进行自动代理
对所有Dao结尾Bean所有方法切面Demo
//XML配置
<!--增强目标-->
<bean id="userDao" class="cn.akwangl.BeanNameAuto.UserDaoImpl"/>
<bean id="customerDao" class="cn.akwangl.BeanNameAuto.CustomerDao"/>
<!--Advice通知方式-->
<bean id="myBeforeAdvice" class="cn.akwangl.BeanNameAuto.MyBeforeAdvice"/>
<bean id="myAroundAdvice" class="cn.akwangl.BeanNameAuto.MyAroundAdvice" />
<!--根据Bean的名字自动创建代理-->
<bean class="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator">
<property name="beanNames" value="*Dao"/>
<property name="interceptorNames" value="myBeforeAdvice"/>
</bean>
//目标对象类
public class UserDaoImpl implements UserDao {
@Override
public void save(User user) {System.out.println("保存用户");}
@Override
public void update(User user) {System.out.println("修改用户");}
@Override
public void findAll() {System.out.println("查询用户");}
@Override
public void delete(Long id) {System.out.println("删除用户");}
}
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("删除客户...");}
}
//通知方式
//环绕通知
public class MyAroundAdvice implements MethodInterceptor {
@Override
public Object invoke(MethodInvocation methodInvocation) throws Throwable {
System.out.println("权限验证...");
Object proceed = methodInvocation.proceed();
System.out.println("日志记录...");
return proceed;
}
}
//前置通知
public class MyBeforeAdvice implements MethodBeforeAdvice {
@Override
public void before(Method method, Object[] args, Object target) throws Throwable {
System.out.println("权限验证...");
}
}
//Test类
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext3.xml")
public class BeanNameAuto_Test {
@Resource(name = "customerDao")
private CustomerDao customerDao;
@Resource(name = "userDao")
private UserDao userDao;
@Test
public void beanNameAuto() {
customerDao.delete();
customerDao.find();
customerDao.save();
customerDao.update();
userDao.findAll();
}
}
//XML配置
<!--增强目标-->
<bean id="userDao" class="cn.akwangl.DefaultAdvisor.UserDaoImpl"/>
<bean id="customerDao" class="cn.akwangl.DefaultAdvisor.CustomerDao"/>
<!--Advice通知方式-->
<bean id="myBeforeAdvice" class="cn.akwangl.DefaultAdvisor.MyBeforeAdvice"/>
<bean id="myAroundAdvice" class="cn.akwangl.DefaultAdvisor.MyAroundAdvice" />
<!--配置切面-->
<bean id="myAdvisor" class="org.springframework.aop.support.RegexpMethodPointcutAdvisor">
<property name="pattern" value=".*save"/>
<property name="advice" ref="myAroundAdvice"/>
</bean>
<bean class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator"/>
//目标类
public class UserDaoImpl implements UserDao {
@Override
public void save(User user) {System.out.println("保存用户");}
@Override
public void update(User user) {System.out.println("修改用户");}
@Override
public void findAll() {System.out.println("查询用户");}
@Override
public void delete(Long id) {System.out.println("删除用户");}
}
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("删除客户...");}
}
//通知方式
//环绕通知
public class MyAroundAdvice implements MethodInterceptor {
@Override
public Object invoke(MethodInvocation methodInvocation) throws Throwable {
System.out.println("权限验证...");
Object proceed = methodInvocation.proceed();
System.out.println("日志记录...");
return proceed;
}
}
//前置通知
public class MyBeforeAdvice implements MethodBeforeAdvice {
@Override
public void before(Method method, Object[] args, Object target) throws Throwable {
System.out.println("权限验证...");
}
}
//Test类
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext4.xml")
public class DefaultAdvisor_Test {
@Resource(name = "customerDao")
private CustomerDao customerDao;
@Resource(name = "userDao")
private UserDao userDao;
@Test
public void beanNameAuto() {
customerDao.delete();
customerDao.find();
customerDao.save();
customerDao.update();
userDao.findAll();
userDao.save(new User());
}
}