如何配置及使用Spring攔截器(通知)
1.Spring有五種通知類型本文着重講述3中:前置通知,後置通知,環繞通知。
2.前置通知:在運行目標方法之前運行。
2.1:前置通知的配置:第一步:新建一個類,實現MethodBeforeAdvice接口,並且複寫其中的before方法。
import java.lang.reflect.Method;
import java.util.Arrays;
import org.springframework.aop.MethodBeforeAdvice;
import org.springframework.stereotype.Component;
@Component("beforeAdvice")
public class BeforeAdvice implements MethodBeforeAdvice
{
@Override
public void before(Method arg0, Object[] arg1, Object arg2) throws Throwable
{
//arg0:目標方法的本身可以通過反射執行此方法
//arg1:arg0方法的參數列表
//arg2:arg2擁有此方法的對象
String name = arg0.getName();
System.out.println(name);
arg0.invoke(arg2.getClass().newInstance());
System.out.println("我是前置通知");
System.out.println("方法本身:" + arg0 + "參數列表:" + Arrays.toString(arg1) + "擁有此方法的對象" + arg2);
}
}
before方法有三個參數,其中Method arg0代表的是目標方法本身(目標方法就是你需要運行的方法)Object[] arg1代表的是目標方法的參數列表,object arg3代表的是目標方法所屬的對象。
第二步:將此類給加上Spring註解,將其放到IOC容器中,或者直接在applicationContent.xml中配置
<bean id="beforeAdvice" class="com.bjsxt.pojo.Student" >
第三步:看看你的spring配置文件的DTD中有沒有以下標紅的三個內容,沒有的話直接粘貼複製我的給加上就好了
<?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"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd"
default-autowire="byName">
沒有上面標紅的三句生命的話,你的xml中是沒有AOP標籤的;
第四步:在applicationContent.xml中配置前置通知
<!-- 配置AOP -->
<aop:config>
<!--
切面定義
expression(固定的):哪些類裏面的哪些方法執行下面的BeforeAdvice
*:第一個*表示返回值:*任意類型
例如:execution(* com.bjsxt.service.impl.*.*(..))
代表com.bjsxt.service.impl包下的任何類的任何方法都觸發通知
com.bjsxt.service.impl.UsersServiceImpl:哪些類*:方法;當前類下面的所有方法(..)參數:任意類型的參數 --><aop:pointcut expression="execution(* com.bjsxt.service.impl.*.*(..))" id="pointcut"/><!-- 通知類型將beforeAdvice關聯到上面的橫切面中(pointcut) --><aop:advisor advice-ref="beforeAdvice"
pointcut-ref="pointcut"/></aop:config></beans>
到此就配置好了,寫個測試類測試一下。
測試類:
import org.junit.Before;
import org.junit.Test;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.stereotype.Component;
@Component("test")
public class SpringTest
{
ClassPathXmlApplicationContext ac =null;
@Before
public void inti()
{
//初始化 得到spring配置文件對象 ac
ac = new ClassPathXmlApplicationContext("applicationContext.xml");
}
@Test
public void test()
{
SpringTest test = (SpringTest)ac.getBean("test");
test.save();
}
public void save()
{
System.out.println("-----------------save---------------");
}
}
控制檯輸出:十一月 15, 2016 9:02:53 上午 org.springframework.context.support.ClassPathXmlApplicationContext prepareRefresh
信息: Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@e6ea0c6: startup date [Tue Nov 15 09:02:53 CST 2016]; root of context hierarchy
十一月 15, 2016 9:02:54 上午 org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
信息: Loading XML bean definitions from class path resource [applicationContext.xml]
save
-----------------save---------------
我是前置通知
-----------------save---------------
方法本身:public void com.bjsxt.test.SpringTest.save()參數列表:[]擁有此方法的對象com.bjsxt.test.SpringTest@581ac8a8
3.通過註解來配置和使用前置通知。
第一步:在applicationContent.xml中開啓通知註解:加入如下的一個標籤就好
<!-- 開啓AOP的註解 -->
<aop:aspectj-autoproxy/>第二步:在通知類的類聲明上加上@Ascept註解。
package com.bjsxt.springaop.aop;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.stereotype.Component;
@Component("myAdciceAnno")
@Aspect
public class MyAdviceAnno
{
@Before(value="execution(* com.bjsxt.test.*.*(..))")//表示的是那些包的那些類的那些方法作爲目標方法,在執行之前需要執行這個前置通知。
public void before()
{
System.out.println("我是前置通知");
}
@After(value="execution(* com.bjsxt.test.*.*(..))")
public void after()
{
System.out.println("我是後置通知");
}
@Around(value="execution(* com.bjsxt.test.*.*(..))")
public void cross(ProceedingJoinPoint pjp) throws Throwable
{
System.out.println("我是環繞通知------------before");
pjp.proceed();
System.out.println("我是環繞通知------------after");
}
}