我們認識完動態代理之後,就可以正式使用spring裏的AOP了,實現spring的AOP有兩種方式:
1)基於xml文件
2)基於註解
1. 通過配置XML文件,實現AOP.
用到的接口及API:
前置通知: MethodBeforeAdvice
public void before(Method arg0, Object[] arg1, Object arg2)throws Throwable{}
後置通知: AfterReturningAdvice
public void afterReturning(Object arg0, Method arg1, Object[] arg2, Object arg3) throws Throwable
MethodInterceptor
public Object invoke(MethodInvocation methodInvocation) throws Throwable {
Object result = methodInvocation.proceed();
return result;
}
用於處理事務: ThrowsAdvice
public void afterThrowing([Method method, Object[] args, Object target, Exception ex)
配置XML文件
<bean id="userTarget" class="code.bean.UserA"></bean> //真實角色
<bean id="methodbeforeTAdvice" class="code.bean.BeforTest"></bean>
<bean id="afterTest" class="code.bean.AfterTest"></bean> //後置通知
<bean id="user" class="org.springframework.aop.framework.ProxyFactoryBean">
<property name="proxyInterfaces"> //真實角色的接口s
<value>code.bean.User</value>
</property>
<property name="target" ref="userTarget"></property>//代理目標
<property name="interceptorNames"> //嵌入通知
<list>
<value>afterTest</value>
<value>methodbeforeTAdvice</value>
</list>
</property>
</bean>
如果在org.springframework.aop.framework.ProxyFactoryBean 的<bean>中未配置proxyInterfaces那麼就會自動通過CGglib實現
2. 用註解的方式實現AOP
1)@component基本註解,標識了一個受Spring管理的組件
2)@Reponsitory 標識的是持久層的組件
3)@service標識的是服務層的組件
4)@Controller 控制層的組件
5)@aspect 表示切面
依賴關係的註解(組件的裝配)
1)@AutoWired -----常用
2) @Resource -----常用
3) @Inject
用法示慄~
@Aspect
@Order(2)
@Component
public class Myaspect {
@Pointcut("execution(public * login(..)) && target(com.neu.controller.UserController)")
public void pointCut(){}
@Before("execution(public * login(..)) && target(com.neu.controller.UserController)")
public void before(JoinPoint joinPoint){
System.out.println(joinPoint.getSignature().getName());
System.out.println("before");
}
@After("pointCut()")
public void after(JoinPoint joinPoint){
System.out.println(joinPoint.getSignature().getName());
System.out.println("after");
}
@Around("pointCut()")
public Object around(ProceedingJoinPoint point) throws Throwable{
System.out.println("before..");
Object object=point.proceed();
System.out.println("after..");
return object;
}
}
注意:切面類一定要添加@Component這樣纔會被XML掃描到
這樣寫需要在xml裏面配置:
1) 注意 添加命名空間
<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:p="http://www.springframework.org/schema/p"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.1.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.1.xsd">
2) 設置掃描路徑
context:component-scan:自動掃描註解的配置文件
base-package:制定一個需要的包,如果多個包之間用,隔開
resource-pattern:更加精確的去確定掃描那個包下的哪個類
<context:component-scan base-package="com.neu" [resource-pattern="" use-default-filters="true"]>
[<context:exclude-filter type="annotation" expression=""/>] --按註釋排除
[<context:include-filter type="assignable" expression=""/>]--按接口單一包含
</context:component-scan>
3)設置切面自動代理(在設置@Aspect和@Before等的前提下)
<aop:aspectj-autoproxy></aop:aspectj-autoproxy>
如果不設置@Aspect和@Before的話,也可以通過只配置xml的方式實現AOP
<bean id="aspect" class="com.neu.main.Myaspect"></bean>
<aop:config>
<aop:pointcut expression="execution(public * login(..)) and target(com.neu.controller.UserController)" id="pointcut"/>
<aop:aspect ref="aspect" order="1">
<aop:after method="before" pointcut-ref="pointcut"/>
<aop:before method="after" pointcut-ref="pointcut"/>
<aop:around method="around" pointcut-ref="pointcut"/>
</aop:aspect>
</aop:config>
5. Spring提供了兩種類型的IOC容器實現
1)BeanFactory :IOC容器最基本的實現
2) ApplicationContext:Web項目常用的獲取bean的方式,特性比較高級,ClassPathXmlApplicationContext這個是用的最多的一種實現方式
4. Spring的注入數值問題:
1)字面值String:value
2) 基本數據類型:字面值
3)引用的是引用類型 Ref這個屬性
4)如果字面值包含了特殊的字符CDATA節進行包裹,<![CDATA[]]>
附錄:
Spring AOP切入點的表達式
1)execution(修飾符? 返回值類型 聲明類型? 方法名稱(方法的參數) 異常類型? )
1 執行任意的public方法
execution(public * * (..))
2 執行任意的get開頭的方法
execution(* get*(..))
3 執行Service包下的所有的類中的任何方法
execution(* com.neusoft.service.*(..))
4 執行至少有一個參數,並且第一個參數的類型爲int類型的方法
execution( * * (java.lang.Integer,..))
5執行Service包下及其子包下的所有的方法
execution(* com.neusoft.service..(..))
6 執行可能會發生異常的所有的方法
execution(* * (..) throws Exception)