1. 代理工厂生成器
顾问代理生成器,当我们声明好顾问后为目标对象生成代理对象。如果项目中存在多个代理对象的话,需要实例化许多的ProxyFactoryBean,我们可以使用顾 问 代理生成器来解决这个问题。
顾问代理生成器主要分两种
- 自动顾问代理生成器:DefaultAdvisorAutoProxyCreator
- 名称顾问代理生成器:BeanNameAutoProxyCreator
4.1 默认顾问代理生成器DefaultAdvisorAutoProxyCreater
4.1.1编写业务接口
public interface ISomeService { public void doSomething(); public void say(); }
4.1.2编写业务接口实现类
public class ISomeServiceImpl implements ISomeService { @Override public void doSomething() { System.out.println("---------真实业务---------"); } @Override public void say() { System.out.println("---------say方法---------"); } }
4.1.3编写切面了实现增强
public class MyAdvice implements MethodBeforeAdvice, AfterReturningAdvice { @Override public void before(Method method, Object[] objects, Object o) throws Throwable { System.out.println("===========前置增强==========="); } @Override public void afterReturning(Object o, Method method, Object[] objects, Object o1) throws Throwable { System.out.println("===========后置增强==========="); } }
4.1.4 编写applicationContext.xml文件
<!--将目标对象声明到Spring容器中--> <bean id="doSomeService" class="cn.spring.advisortest.ISomeServiceImpl"></bean> <bean id="beanTest" class="cn.spring.advisortest.BeanTest"></bean> <!--将advice声明到容器中--> <bean id="advice" class="cn.spring.advisortest.MyAdvice"></bean> <!--配置顾问:包装通知--> <bean id="advisor" class="org.springframework.aop.support.NameMatchMethodPointcutAdvisor"> <property name="advice" ref="advice"></property> <!--指定为say方法和doSomething方法实现增强--> <property name="mappedNames" value="doSomething,say"></property> </bean> <!--默认顾问自动代理生成器--> <bean class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator"></bean>
4.1.5 编写测试类
@org.junit.Test public void test1() { ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml"); ISomeService proxyfactory = (ISomeService) context.getBean("doSomeService"); proxyfactory.doSomething(); System.out.println(); proxyfactory.say(); System.out.println(); BeanTest beanTest = (BeanTest) context.getBean("beanTest"); beanTest.doSome(); }
4.2名称顾问代理生成器:BeanNameAutoProxyCreator
4.2.1编写业务接口
public interface ISomeService { public void doSomething(); public void say(); }
4.2.2编写业务接口实现类
public class ISomeServiceImpl implements ISomeService { @Override public void doSomething() { System.out.println("---------真实业务---------"); } @Override public void say() { System.out.println("---------say方法---------"); } }
4.2.3编写切面了实现增强
public class MyAdvice implements MethodBeforeAdvice, AfterReturningAdvice { @Override public void before(Method method, Object[] objects, Object o) throws Throwable { System.out.println("===========前置增强==========="); } @Override public void afterReturning(Object o, Method method, Object[] objects, Object o1) throws Throwable { System.out.println("===========后置增强==========="); } }
4.2.4 编写applicationContext.xml文件
<!--将目标对象声明到Spring容器中--> <bean id="doSomeService" class="cn.spring.advisortest.ISomeServiceImpl"></bean> <bean id="beanTest" class="cn.spring.advisortest.BeanTest"></bean> <!--将advice声明到容器中--> <bean id="advice" class="cn.spring.advisortest.MyAdvice"></bean> <!--配置顾问:包装通知--> <bean id="advisor" class="org.springframework.aop.support.NameMatchMethodPointcutAdvisor"> <property name="advice" ref="advice"></property> <!--指定为say方法和doSomething方法实现增强--> <property name="mappedNames" value="doSomething,say"></property> </bean> <!--BeanName自动代理生成器--> <bean class="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator"> <!--配置BeanName--> <property name="beanNames" value="doSomeService,beanTest"></property> <!--拦截顾问--> <property name="interceptorNames" value="advisor"></property> </bean>
4.2.5编写测试类
@org.junit.Test public void test1() { ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml"); ISomeService proxyfactory = (ISomeService) context.getBean("doSomeService"); proxyfactory.doSomething(); System.out.println(); proxyfactory.say(); System.out.println(); BeanTest beanTest = (BeanTest) context.getBean("beanTest"); beanTest.doSome(); }
2. 顾问包装通知
通知(advice)是Spring中的一种比较简单的切面,只能将切面织入到目标类的所有方法中,而无法对指定方法进行增强
顾问(advisor)是Spring提供的另外一种切面,可以织入到指定的方法中 接口 PointcutAdvisor
实现类:NameMatchMethodPointcutAdvisor(基于方法名称的增强顾问),RegexpMethodPointcutAdvice(基于正则表达式的增强顾问)
2.1 NameMatchMethodPointcutAdvisor
5.1.1编写业务接口
public interface ISomeService { public void doSomething(); public void say(); }
5.1.2编写业务接口实现类
public class ISomeServiceImpl implements ISomeService { @Override public void doSomething() { System.out.println("---------真实业务---------"); } @Override public void say() { System.out.println("---------say方法---------"); } }
5.1.3编写切面类实现增强
public class MyAdvice implements MethodBeforeAdvice, AfterReturningAdvice { @Override public void before(Method method, Object[] objects, Object o) throws Throwable { System.out.println("===========前置增强==========="); } @Override public void afterReturning(Object o, Method method, Object[] objects, Object o1) throws Throwable { System.out.println("===========后置增强==========="); } }
5.1.4编写applicationContext.xml文件
<!--将目标对象声明到Spring容器中--> <bean id="doSomeService" class="cn.spring.advisortest.ISomeServiceImpl"></bean> <bean id="beanTest" class="cn.spring.advisortest.BeanTest"></bean> <!--将advice声明到容器中--> <bean id="advice" class="cn.spring.advisortest.MyAdvice"></bean> <!--配置顾问:包装通知--> <bean id="advisor" class="org.springframework.aop.support.NameMatchMethodPointcutAdvisor"> <property name="advice" ref="advice"></property> <!--指定为say方法和doSomething方法实现增强--> <property name="mappedNames" value="doSomething,say"></property> </bean> <!--默认顾问自动代理生成器--> <bean class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator"></bean>
5.1.5 编写测试类
@org.junit.Test public void test1() { ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml"); ISomeService proxyfactory = (ISomeService) context.getBean("doSomeService"); proxyfactory.doSomething(); System.out.println(); proxyfactory.say(); System.out.println(); BeanTest beanTest = (BeanTest) context.getBean("beanTest"); beanTest.doSome(); }
2.2 RegexpMethodPointcutAdvice
5.2.1 编写业务接口
public interface ISomeService { public void doSomething(); public void say(); }
5.2.2编写业务接口实现类
public class ISomeServiceImpl implements ISomeService { @Override public void doSomething() { System.out.println("---------真实业务---------"); } @Override public void say() { System.out.println("---------say方法---------"); } }
5.2.3编写切面类实现增强
public class MyAdvice implements MethodBeforeAdvice, AfterReturningAdvice { @Override public void before(Method method, Object[] objects, Object o) throws Throwable { System.out.println("===========前置增强==========="); } @Override public void afterReturning(Object o, Method method, Object[] objects, Object o1) throws Throwable { System.out.println("===========后置增强==========="); } }
5.2.4编写applicationContext.xml文件
<!--将目标对象声明到Spring容器中--> <bean id="doSomeService" class="cn.spring.advisortest.ISomeServiceImpl"></bean> <bean id="beanTest" class="cn.spring.advisortest.BeanTest"></bean> <!--将advice声明到容器中--> <bean id="advice" class="cn.spring.advisortest.MyAdvice"></bean> <!--配置顾问:包装通知--> <bean id="advisor" class="org.springframework.aop.support.RegexpMethodPointcutAdvisor"> <property name="advice" ref="advice"></property> <!--指定为say方法实现增强 . 代表单个字符 * 代表前一项出现0-n次 + 代表前一项出现1-n次 至少包含两个字符--> <property name="patterns"> <list> <value>.*do.*</value> <value>.*sa.*</value> </list> </property> </bean> <!--BeanName自动代理生成器--> <bean class="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator"> <!--配置BeanName--> <property name="beanNames" value="doSomeService,beanTest"></property> <!--拦截顾问--> <property name="interceptorNames" value="advisor"></property> </bean> <!--BeanName自动代理生成器--> <bean class="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator"> <!--配置BeanName--> <property name="beanNames" value="doSomeService"></property> <!--拦截顾问--> <property name="interceptorNames" value="advisor"></property> </bean>
5.2.5编写测试类
@org.junit.Test public void test1() { ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml"); ISomeService proxyfactory = (ISomeService) context.getBean("doSomeService"); proxyfactory.doSomething(); System.out.println(); proxyfactory.say(); System.out.println(); }