SpringSpring中的四种增强和顾问

Posted 明渃筱曦

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了SpringSpring中的四种增强和顾问相关的知识,希望对你有一定的参考价值。

Spring中的四种增强有那四种?

前置增强    后置增强  环绕增强  异常增强

先编写接口和实体类  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();
   }

 第二种方法:正则方法切入点顾问

同样是饮用上面的接口和实现类,在配置文件中:

<?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="demo16.SomeServiceImpl"></bean>
    <bean id="beforeAdvice" class="demo16.BeforeAdvice"></bean>

    <bean id="advisor" class="org.springframework.aop.support.RegexpMethodPointcutAdvisor">
        <property name="advice" ref="beforeAdvice"></property>
        <property name="pattern" 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>
<property name="pattern" value=".*do.*"></property>

这个节点中name还有一个值是:patterns,其value值是:

<property name="patterns" value=".*Some,.*Any"></property>

这种方法用的是正则的符号

 

以上是关于SpringSpring中的四种增强和顾问的主要内容,如果未能解决你的问题,请参考以下文章

list的四种遍历方式

mysql查看版本的四种方法

分布式架构在云计算平台中的四种主要应用及优缺点分析 | 最佳实践

Spring通知,顾问,增强

Java中的四种内部类总结

顾问和注解