Sping(七)Sping四种增强和顾问
前置增强 后置增强 环绕增强 异常增强
先编写接口和实体类 ISomeService和SomeServiceImpl
package demo10; /** * Created by mycom on 2018/3/8. */ public interface ISomeService { public void doSome(); }
package demo10; /** * Created by mycom on 2018/3/8. */ public class SomeServiceImpl implements ISomeService { public void doSome() { System.out.println("================="); } }
先来说第一个前置增强,直接用例子来说明
package demo10; import org.springframework.aop.MethodBeforeAdvice; import java.lang.reflect.Method; /** * Created by mycom on 2018/3/8. */ public class BeforeAdvice implements MethodBeforeAdvice { public void before(Method method, Object[] objects, Object o) throws Throwable { System.out.println("=========before"); } }
在配置文件中
<?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="service" class="demo10.SomeServiceImpl"></bean> <bean id="beforeAdvice" class="demo10.BeforeAdvice"></bean> <bean id="proxyService" class="org.springframework.aop.framework.ProxyFactoryBean"> <property name="target" ref="service"></property> <property name="interceptorNames" value="beforeAdvice"></property> </bean> </beans>
@Test public void t1(){ ApplicationContext context=new ClassPathXmlApplicationContext("applicationContextBefore.xml"); ISomeService proxyService =(ISomeService) context.getBean("proxyService"); proxyService.doSome(); }
运行的结果是
2.后置增强和前置增强一样,只是改一改配置文件里的名称就可以
<?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="service" class="demo11.SomeServiceImpl"></bean> <bean id="afterAdvice" class="demo11.AfterAdvice"></bean> <bean id="proxyService" class="org.springframework.aop.framework.ProxyFactoryBean"> <property name="target" ref="service"></property> <property name="interceptorNames" value="afterAdvice"></property> </bean> </beans>
3.环绕增强
直接饮用上面的接口和实现类了
在创建另一个类 MethodAdvice
package demo12; import org.aopalliance.intercept.MethodInterceptor; import org.aopalliance.intercept.MethodInvocation; /** * Created by mycom on 2018/3/8. */ public class MethodAdvice implements MethodInterceptor { public Object invoke(MethodInvocation methodInvocation) throws Throwable { System.out.println("前置增强"); Object result = methodInvocation.proceed(); System.out.println("后置增强"); return result; } }
<?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="service" class="demo12.SomeServiceImpl"></bean> <bean id="methodAdvice" class="demo12.MethodAdvice"></bean> <bean id="proxyService" class="org.springframework.aop.framework.ProxyFactoryBean"> <property name="target" ref="service"></property> <property name="interceptorNames" value="methodAdvice"></property> </bean> </beans>
4.异常增强
package demo13; import org.aopalliance.intercept.MethodInterceptor; import org.aopalliance.intercept.MethodInvocation; import org.springframework.aop.ThrowsAdvice; /** * Created by mycom on 2018/3/8. */ public class MyThroesAdvice implements ThrowsAdvice { public void afterThrowing(Exception ex){ System.out.println("网络出现错误"); } }
<?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="service" class="demo13.SomeServiceImpl"></bean> <bean id="throwsAdvice" class="demo13.MyThroesAdvice"></bean> <bean id="proxyService" class="org.springframework.aop.framework.ProxyFactoryBean"> <property name="target" ref="service"></property> <property name="interceptorNames" value="throwsAdvice"></property> </bean> </beans>
@Test public void t2(){ ApplicationContext context=new ClassPathXmlApplicationContext("applicationContextThrows.xml"); ISomeService proxyService =(ISomeService) context.getBean("proxyService"); try{ proxyService.doSome(); }catch (Exception ex){ ex.printStackTrace(); }
5.advisor 是顾问的意思 正对某一个方法增强
还有一个词是通知 advice 我自己的理解是 通知视同只所有人,顾问是针对某个人顾问,这样方便记忆
现在在ISomeService接口中在添加一个方法doAny(),在实现类中重写这个方法
那么在配置文件中
<?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="service" class="demo14.SomeServiceImpl"></bean> <bean id="beforeAdvice" class="demo14.BeforeAdvice"></bean> <!--与其他不一样的地方--> <bean id="advisor" class="org.springframework.aop.support.NameMatchMethodPointcutAdvisor"> <property name="advice" ref="beforeAdvice"></property> <property name="mappedNames" value="do*"></property> </bean> <bean id="proxyService" class="org.springframework.aop.framework.ProxyFactoryBean"> <property name="target" ref="service"></property> <property name="interceptorNames" value="advisor"></property> </bean> </beans>
这个配置文件可以对比着之前写的配置文件看看有什么不同之处
@Test public void t2(){ ApplicationContext context=new ClassPathXmlApplicationContext("applicationContextAdvisor.xml"); ISomeService proxyService =(ISomeService) context.getBean("proxyService"); proxyService.doSome(); proxyService.doAny(); }