国产一级a片免费看高清,亚洲熟女中文字幕在线视频,黄三级高清在线播放,免费黄色视频在线看

打開APP
userphoto
未登錄

開通VIP,暢享免費電子書等14項超值服

開通VIP
Spring高級程序設計 6 Spring AOP 進階
1AOP簡介
通知(Advice):通知定義了切面是什么以及何時使用。除了要描述切面要完成的工作,通知還解決了何時執(zhí)行這個工作的問題。
連接點(Joinpoint):連接點是在程序執(zhí)行過程中能夠插入切面的一個點。這個店可以是方法被調(diào)用時、異常被拋出時、甚至字段被編輯時。切面代碼可以通過這些點插入到程序的一般流程之中,從而添加新的行為。
切入點(Poincut):切入點可以縮小切面通知的連接點的范圍。如果說通知定義了切面的“什么”和“何時”,那么切入點就定義了“何地”。
切面(Aspect):切面是通知和切入點的組合。
引入(Introduction):“引入”允許我們向現(xiàn)有的類添加新方法或者屬性。
目標(Target):被通知的對象。
代理(Proxy):是向目標對象應用通知之后被創(chuàng)建的對象。
織入(Weaving):是把切面應用到目標對象來創(chuàng)建新的代理對象的過程。編譯時、類加載時、運行時。
主流的Spring:
AspectJ\JBoss AOP\Spring AOP
Spring對AOP的支持:
經(jīng)典的基于代理的AOP(各版本Spring);
@AspectJ注解驅動的切面。(僅Spring2.0);
純POJO切面(僅Spring2.0);
注入式AspectJ切面(各版本Spring)。
Spring通知是用Java編寫的:
Spring創(chuàng)建的全部通知都是用標準的Java編寫的。
Spring在運行時通知對象:
Spring利用代理類包裹切面,從而把他們注入到Spring管理的Bean里。
Spring只支持方法連接點:
由于Spring是基于動態(tài)代理的,他只支持方法連接點。
2創(chuàng)建典型的Spring切面
Spring AOP的通知類型:
Before(前):org.springframework.aop.MethodBeforeAdvice
After-returning(返回后):org.springframework.aop.AfterReturningAdvice
After-throwing(拋出后):org.springframework.aop.ThrowsAdvice
Around(包圍):org.aopalliance.intercept.MethodInterceptor
Introduction(引入):org.springframework.aop.IntroductionInterceptor
除了Around之外,這些接口都屬于Spring。
demo:
通知調(diào)用的方法類view plaincopy to clipboardprint?
package cn.partner4java.springidol;
/**
* 觀眾需要做的動作
* (就是當調(diào)用演唱的時候,把這些動作順序的加入到演唱的前后)
* @author partner4java
*
*/
public class Audience {
public void takeSeats(){
System.out.println("The audience is taking their seats.");
}
public void appluad(){
System.out.println("CLAP CLAP!");
}
public void demandRefund(){
System.out.println("Boo! We want our moeny back!");
}
}
定義兩種實現(xiàn)方式的通知:
方式1:利用前置、后置、異常通知view plaincopy to clipboardprint?
package cn.partner4java.springidol;
import java.lang.reflect.Method;
import org.springframework.aop.AfterReturningAdvice;
import org.springframework.aop.MethodBeforeAdvice;
import org.springframework.aop.ThrowsAdvice;
/**
* Audience 的通知
* 利用前置、后置、異常通知
* @author partner4java
*
*/
public class AudienceAdvice implements MethodBeforeAdvice,
AfterReturningAdvice, ThrowsAdvice {
private Audience audience;
public void setAudience(Audience audience) {
this.audience = audience;
}
public void before(Method method, Object[] args, Object target)
throws Throwable {
audience.takeSeats();
}
public void afterReturning(Object returnValue, Method method,
Object[] args, Object target) throws Throwable {
audience.appluad();
}
//There are not any methods on this interface, as methods are invoked by reflection.
public void afterThrowing(Throwable throwable){
audience.demandRefund();
}
}
方式2:環(huán)繞通知view plaincopy to clipboardprint?
package cn.partner4java.springidol;
import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
/**
* Audience 的環(huán)繞通知
* @author partner4java
*
*/
public class AudienceAroundAdvice implements MethodInterceptor {
private Audience audience;
public void setAudience(Audience audience) {
this.audience = audience;
}
public Object invoke(MethodInvocation invocation) throws Throwable {
try {
audience.takeSeats();
Object returnValue = invocation.proceed();
audience.appluad();
return returnValue;
} catch (Exception e) {
audience.demandRefund();
throw e;
}
}
}
定義切點和通知者:
聲明正則表達式切點、聯(lián)合切點與通知者:view plaincopy to clipboardprint?
<?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: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/aop
http://www.springframework.org/schema/aop/spring-aop.xsd">
<bean id="audience" class="cn.partner4java.springidol.Audience"/>
<!-- 通知(Advice):通知定義了切面是什么以及何時使用 -->
<bean id="advice1" class="cn.partner4java.springidol.AudienceAdvice">
<property name="audience" ref="audience"></property>
</bean>
<bean id="advice2" class="cn.partner4java.springidol.AudienceAroundAdvice">
<property name="audience" ref="audience"></property>
</bean>
<!-- 切入點(Poincut):切入點可以縮小切面通知的連接點的范圍 -->
<bean id="performancePointcut1" class="org.springframework.aop.support.JdkRegexpMethodPointcut">
<property name="pattern" value=".*perform"></property>
</bean>
<!-- 定義AspectJ方式切點 -->
<bean id="performancePointcut2" class="org.springframework.aop.aspectj.AspectJExpressionPointcut">
<property name="expression" value="execution(* Performer+.perform(..))"></property>
</bean>
<!-- 切面(Aspect):切面是通知和切入點的組合  (通知者)-->
<bean id="audienceAdvisor1" class="org.springframework.aop.support.DefaultPointcutAdvisor">
<property name="advice" ref="advice1"></property>
<property name="pointcut" ref="performancePointcut1"></property>
</bean>
<bean id="audienceAdvisor2" class="org.springframework.aop.support.RegexpMethodPointcutAdvisor">
<property name="advice" ref="advice1"></property>
<property name="pattern" value=".*perform"></property>
</bean>
<bean id="performer" class="cn.partner4java.springidol.PerformerBean"></bean>
</beans>
定義AspectJ切點
正則表達式雖然可以作為切點定義語言來使用,但他并不是針對切點而創(chuàng)建的,其主要用途換是文本解析。與之相比,從AspectJ里定義切點的方式就可以看出AspectJ的切點語言是一種真正的切點表達式語言。
使用ProxyFactoryBean:
代理(Proxy):是向目標對象應用通知之后被創(chuàng)建的對象
利用ProxyFactoryBean代理被切面的對象。view plaincopy to clipboardprint?
<?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: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/aop
http://www.springframework.org/schema/aop/spring-aop.xsd">
<bean id="audience" class="cn.partner4java.springidol.Audience"/>
<!-- 通知(Advice):通知定義了切面是什么以及何時使用 -->
<bean id="advice1" class="cn.partner4java.springidol.AudienceAdvice">
<property name="audience" ref="audience"></property>
</bean>
<bean id="advice2" class="cn.partner4java.springidol.AudienceAroundAdvice">
<property name="audience" ref="audience"></property>
</bean>
<!-- 切入點(Poincut):切入點可以縮小切面通知的連接點的范圍 -->
<bean id="performancePointcut1" class="org.springframework.aop.support.JdkRegexpMethodPointcut">
<property name="pattern" value=".*perform"></property>
</bean>
<!-- 定義AspectJ方式切點 -->
<bean id="performancePointcut2" class="org.springframework.aop.aspectj.AspectJExpressionPointcut">
<property name="expression" value="execution(* Performer+.perform(..))"></property>
</bean>
<!-- 切面(Aspect):切面是通知和切入點的組合  (通知者)-->
<bean id="audienceAdvisor1" class="org.springframework.aop.support.DefaultPointcutAdvisor">
<property name="advice" ref="advice1"></property>
<property name="pointcut" ref="performancePointcut1"></property>
</bean>
<bean id="audienceAdvisor2" class="org.springframework.aop.support.RegexpMethodPointcutAdvisor">
<property name="advice" ref="advice1"></property>
<property name="pattern" value=".*perform"></property>
</bean>
<!-- 使用ProxyFactoryBean -->
<bean id="performer" class="cn.partner4java.springidol.PerformerBean"></bean>
<bean id="duke" class="org.springframework.aop.framework.ProxyFactoryBean">
<property name="target" ref="performer"></property>
<property name="interceptorNames" value="audienceAdvisor1"></property>
<property name="proxyInterfaces" value="cn.partner4java.springidol.Performer"></property>
</bean>
</beans>
調(diào)用:view plaincopy to clipboardprint?
package cn.partner4java.springidol;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class HelloWorld {
public static void main(String[] args) {
ApplicationContext ctx = new ClassPathXmlApplicationContext(
"/META-INF/spring/springido.xml");
Performer performer = (Performer) ctx.getBean("duke");
performer.perform();
}
}
3自動代理
@AspectJ注解
@AspectJ跟AspectJ沒有關系。他是Spring用來解析連接點和通知的一組java 5注解。
demo1:view plaincopy to clipboardprint?
package cn.partner4java.spring.aspectj;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
/**
* 通過@Aspect注解實現(xiàn)日志記錄
* @author partner4java
*
*/
@Aspect
public class LoggingAspect {
@Around("execution(* cn.partner4java.spring.aspectj.*.*(..))")
public Object log(ProceedingJoinPoint joinPoint) throws Throwable {
System.out.println("begin");
Object ret = joinPoint.proceed();
System.out.println("after");
return ret;
}
}
view plaincopy to clipboardprint?
package cn.partner4java.spring.aspectj;
/**
* 被測試的bean
* @author partner4java
*
*/
public class TestBean {
public void work() {
System.out.println("work");
}
public void stop() {
System.out.println("stop");
}
}
view plaincopy to clipboardprint?
<?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: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/aop
http://www.springframework.org/schema/aop/spring-aop.xsd">
<bean id="test" class="cn.partner4java.spring.aspectj.TestBean"/>
<bean class="cn.partner4java.spring.aspectj.LoggingAspect">
</bean>
<aop:aspectj-autoproxy />
</beans>
view plaincopy to clipboardprint?
package cn.partner4java.spring.aspectj;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class LoggingAspectDemo {
public static void main(String[] args) {
ApplicationContext ac = new ClassPathXmlApplicationContext(
"/META-INF/spring/ataspectjdemo1-context.xml"
);
TestBean testBean = (TestBean) ac.getBean("test");
testBean.work();
testBean.stop();
//        后臺打?。?div style="height:15px;">
//        begin
//        work
//        after
//        begin
//        stop
//        after
}
}
@AspectJ方面詳解
切入點聲明表達式可以引入別人的表達式如:
@Pointcut("execution(* com.apress.prospring2.ch06.simple.TestBean.*(..))")
private void testBeanExecution() { }
@Around("testBeanExecution()")
public Object log(ProceedingJoinPoint pjp) throws Throwable {
或者
@Around("SystemPointcuts.testBeanExecution()")
public Object log(ProceedingJoinPoint pjp) throws Throwable {
切入點表達式:
execution:匹配方法執(zhí)行連接點。我們可以指定包、類或者方法名,以及方法的可見性、返回值和參數(shù)類型。這是應用的最為廣泛的切入點表達式。
within:匹配那些在已聲明的類型中執(zhí)行的連接點。
this:通過用bean引用的類型跟指定的類型做對比來匹配連接點。
args:通過比較方法的參數(shù)類型跟指定的參數(shù)類型來匹配連接點。
@target:通過檢查調(diào)用目標對象是否具有特定注解來匹配連接點。
@args:跟args類似,不過@args檢查的是方法參數(shù)的注解而不是他們的類型。
@within:跟within相似,這個表達式匹配那些帶有特定注解的類中執(zhí)行的連接點。
@annotation:通過檢查講被調(diào)用的方法上的注解是否為指定的注解來匹配連接點。
bean:通過比較bean的ID來匹配連接點,我們也可以在bean名模式中使用通配符。
我們可以使用||(或)和&&(與)組合切入點表達式。!(非)取否。
探討切入點表達式:
1、execution表達式
如:
* com.partner4java..*.*(..)
第一個*表示任意返回類型,..*表示包下的所有類,*(..)表示任意方法和任意參數(shù).
2、within表達式
within(com..TestBean):匹配從TestBean的方法中產(chǎn)生的調(diào)用
within(com..*):匹配在com包及其子包的任意類中對任意方法調(diào)用的執(zhí)行過程的切入點。
3、this表達式
this表達式和within表達有些類似,但是不能使用..或者*等通配符。
this(class-name)
4、target表達式
和this完全一樣。
5、args表達式
args(type-pattern?(,type-pattern)*)
可以使用..通配符
execution(* SimpleBean.*(String,String))
args(Integer,..,String)
6、@target表達式
4定義純粹的POJO切面
Spring開發(fā)組意識到使用ProxyFactoryBean有些欠優(yōu)雅,所以致力于提供一種更好的切面聲明方式。Spring 2.0里新的XML配置元素就體現(xiàn)出了這種努力。
Spring 2.0的AOP配置元素:
<aop:advisor>:定義一個AOP通知者
<aop:after>:定義一個AOP后通知(不考慮被通知的方法是否成功返回)
<aop:after-returning>:定義一個AOP返回后通知
<aop:after-throwing>:定義一個AOP拋出后通知
<aop:around>:定義一個AOP包圍通知
<aop:aspect>:定義一個切面
<aop:before>:頂一個AOP前置通知
<aop:config>:頂級AOP元素。大多數(shù)<aop:*>元素必須包含在
<aop:pointcut>:定義一個切點
demo:
使用上面的元素來定義一個完整的切面,其中包含通知者和切入點,不同的是,我們不需要自己聲明代理(Proxy)就完成了織入(Weaving)。view plaincopy to clipboardprint?
<?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: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/aop
http://www.springframework.org/schema/aop/spring-aop.xsd">
<bean id="audience" class="cn.partner4java.springidol.Audience"/>
<bean id="performer" class="cn.partner4java.springidol.PerformerBean"></bean>
<aop:config>
<aop:aspect ref="audience">
<aop:pointcut expression="execution(* *.perform*(..))" id="performance"/>
<aop:before method="takeSeats" pointcut-ref="performance"/>
<aop:after-returning method="appluad" pointcut-ref="performance"/>
<aop:after-throwing method="demandRefund" pointcut-ref="performance"/>
</aop:aspect>
</aop:config>
</beans>
調(diào)用:view plaincopy to clipboardprint?
ApplicationContext ctx = new ClassPathXmlApplicationContext(
"/META-INF/spring/spring-pojo1.xml");
Performer performer = (Performer) ctx.getBean("performer");
performer.perform();
5注入AspectJ切面
雖然Spring AOP對于大多數(shù)切面程序來說就足夠了,但是與AspectJ相比,他只能算是一個功能較弱的AOP解決方案。AspectJ提供了Spring AOP不可能實現(xiàn)的多種切點類型。
(如果想更深入的了解AspectJ,可以閱讀Raminvas Ladded的AspectJ in Action(Manning,2003))
demo:
創(chuàng)建第一個AspectJ方面。
Spring通過添加aspectOf()方法增加對AspectJ的支持,不需要你額外的管理容器。
創(chuàng)建一個aj格式的文件,也就是AspectJ的切面:view plaincopy to clipboardprint?
package cn.partner4java.aspectj;
public aspect StockServiceAspect {
private String suffix;
private String prefix;
public void setPrefix(String prefix) {
this.prefix = prefix;
}
public void setSuffix(String suffix) {
this.suffix = suffix;
}
pointcut doServiceCall() :
execution(* cn.partner4java.aspectj.*.*(..));
before() : doServiceCall() {
System.out.println(this.prefix);
}
after() : doServiceCall() {
System.out.println(this.suffix);
}
}
配置文件:額外添加factory-method="aspectOf"知名是AspectJ文件view plaincopy to clipboardprint?
<?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="stockService" class="cn.partner4java.aspectj.DefaultStockService"/>
<!-- 額外添加factory-method="aspectOf"知名是AspectJ文件 -->
<bean class="cn.partner4java.aspectj.StockServiceAspect"
factory-method="aspectOf">
<property name="prefix" value="Before call"/>
<property name="suffix" value="After call"/>
</bean>
</beans>
調(diào)用:為了讓示例程序正常運行,我們必須使用AspectJ編譯器(需要像使用JDK那樣安裝,配置環(huán)境變量等)view plaincopy to clipboardprint?
package cn.partner4java.aspectj;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class HelloWorld {
public static void main(String[] args) {
//為了讓示例程序正常運行,我們必須使用AspectJ編譯器
ApplicationContext ac = new ClassPathXmlApplicationContext(
"/META-INF/spring/aspectjdemo1-context.xml"
);
StockService stockService = (StockService) ac.getBean("stockService");
System.out.println(stockService.getStockLevel("ABC"));
}
}
AspectJ還可以指定“加載時織入”:
使用spring-agent.jar作為JVM代理來替代<aop:aspectj-autoproxy/>,并使用上下文命名空間來初始化加載時織入。
除了ApplicationContext的XML配置文件之外,還需要創(chuàng)建META-INF/aop.xml文件。這個aop.xml文件是一個標準的AspectJ組件。他告訴AspectJ注入器在加載時織入哪些類。
Spring加入<context:load-time-weaver>,可以配置aspectj-weaving,設置on或者off設置開啟或關閉織入。
本站僅提供存儲服務,所有內(nèi)容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權內(nèi)容,請點擊舉報。
打開APP,閱讀全文并永久保存 查看更多類似文章
猜你喜歡
類似文章
InfoQ: Spring 2.0的新特性和應用實踐
<aop:aspectj-autoproxy />作用
9,000+ 字,徹底征服 Spring AOP!
Spring源碼分析之AOP從解析到調(diào)用
架構師面試之-------------mysql和 spring aop實現(xiàn)
3.spring中aop的注解實現(xiàn)方式簡單實例
更多類似文章 >>
生活服務
分享 收藏 導長圖 關注 下載文章
綁定賬號成功
后續(xù)可登錄賬號暢享VIP特權!
如果VIP功能使用有故障,
可點擊這里聯(lián)系客服!

聯(lián)系客服