當前位置:首頁 » 存儲配置 » 如何配置aop

如何配置aop

發布時間: 2022-01-11 12:33:03

Ⅰ springaop怎麼在xml文件中配置

就是首先需要的
<tx:advice id="txAdvice" transaction-manager="txManager">
<tx:attributes>
<tx:method name="save*" propagation="REQUIRED" />
<tx:method name="update*" propagation="REQUIRED" />
<tx:method name="delete*" propagation="REQUIRED" />
<tx:method name="find*" propagation="SUPPORTS" />
</tx:attributes>
</tx:advice>
<aop:config>
<aop:pointcut expression="execution(* com.linksky.ssm.service.*.*(..))"
id="txPointcut" />
<aop:advisor advice-ref="txAdvice" pointcut-ref="txPointcut" />
</aop:config>

Ⅱ spring的aop怎樣實現

  • 實現原理

  • 前面在學習代理模式的時候,了解到代理模式分為動態代理和靜態代理。現在我們就以代理模式為基礎先實現我們自己的AOP框架,再來研究Spring的AOP的實現原理。

    先以靜態代理實現,靜態代理關鍵是在代理對象和目標對象實現共同的介面,並且代理對象持有目標對象的引用。

    公共介面代碼:

    通過上面例子,可以發現通過動態代理和發射技術,已經基本實現了AOP的功能,如果我們只需要在方法執行前列印日誌,則可以不實現end()方法,這樣就可以控制列印的時機了。如果我們想讓指定的方法列印日誌,我們只需要在invoke()方法中加一個對method名字的判斷,method的名字可以寫在xml文件中,這樣我們就可以實現以配置文件進行解耦了,這樣我們就實現了一個簡單的spring aop框架。

Ⅲ spring mvc 中怎麼配置aop呢

在 beans 裡面

<aop:config>
<aop:aspect id="TestAspect" ref="aspectBean">
<!--配置com.spring.service包下所有類或介面的所有方法-->
<aop:pointcut id="businessService"
expression="execution(* com.spring.service.*.*(..))" />
<aop:before pointcut-ref="businessService" method="doBefore"/>
<aop:after pointcut-ref="businessService" method="doAfter"/>
<aop:around pointcut-ref="businessService" method="doAround"/>
<aop:after-throwing pointcut-ref="businessService" method="doThrowing" throwing="ex"/>
</aop:aspect>
</aop:config>

<bean id="aspectBean" class="com.spring.aop.TestAspect" />
<bean id="aService" class="com.spring.service.AServiceImpl"></bean>
<bean id="bService" class="com.spring.service.BServiceImpl"></bean>

Ⅳ spring怎麼實現aop,攔截器怎麼配置的

你指的是aop:config和mvc:interceptors的區別嗎?簡單的講他們的區別是:aop:config是針對類方法的攔截,適用於所有的java類方法的攔截,包括javase。只需要在applicationContext.xml里設置就行了。mvc:interceptors是針對web請求的攔截,與java.servlet.Filter很類似。通過設置需要攔截的url請求從而攔截請求方法。其他方面兩者都差不多。

Ⅳ spring配置aop的方式有哪些

1. 基於xml配置文件的代理配置方式
這種方式在2.0以後很少用了,原因是配置項過多,過於繁瑣。但對於理解Spring AOP還是很有幫助的
1.1 定義通知
<bean id="advice" class="yourAdviceImpl" />
1.2 定義切點
要定義一個切點,可以選擇使用正則表達式方式聲明的切點或者AspectJ方式聲明的切點。對正則表達式切點,使用Perl5RegexpMethodPointcut或JdkRegexpMethodPointcut(Java
1.4以上版本,不需要Jakarta ORO的支持了);對AspectJ切點,使用AspectJExpressPointcut
<bean id="pointcut" class="org.springframework.aop.support.JdkRegexpMethodPointcut">
<property name="pattern" value="yourRegularExpression" />
</bean>
<bean id="pointcut" class="org.springframework.aop.aspectj.AspectJExpressionPointcut">
<property name="expression" value="yourAspectJExpression" />
</bean>
1.3 定義通知者
DefaultPointcutAdvisor是Spring提供的默認通知者,它需要提供通知和切點的引用。
Spring也提供了RegexpMethodPointcutAdvisor和來對應兩種聲明切點的方式,不用再單獨定義切點。
<bean id="advisor" class="org.springframework.aop.support.DefaultPointcutAdvisor">
<property name="advice" ref="advice" />
<property name="pointcut" ref="pointcut" />
</bean>

<bean id="advisor" class="org.springframework.aop.support.RegexpMethodPointcutAdvisor">
<property name="advice" ref="advice" />
<property name="pattern" value="yourRegularExpression" />
</bean>

<bean id="advisor" class="org.springframework.aop.aspectj.AspectJExpressionPointcut">
<property name="advice" ref="advice" />
<property name="expression" value="yourAspectjExpression" />
</bean>

1.4 定義ProxyFactoryBean
<bean id="yourBean" class="org.springframework.aop.framework.ProxyFactoryBean>
<property name="target" ref="yourTargetBean" />
<property name="interceptorNames" value="advisor" />
<property name="proxyInterfaces" value="interfaceClass" />
</bean>
interceptorNames和proxyInterfaces都是數組屬性,所以可以聲明要使用的一個list,也可以讓Spring自動把單個值轉化為數組

上面明確定義了要對那個targetBean應用代理生成切面實例。如果不想限制targetBean,可以讓Spring為所有匹配切點聲明的bean生成切面實例,這樣就不用一個個定義ProxyFactoryBean了,只需要定義
<bean class="org.springframework.aop.framework.autoproxy." />
這是一個BeanPostProcessor,所以Spring會自動識別並在bean的聲明周期使用

2 利用2.0以後使用aop標簽
<aop:config>
<aop:aspect ref="">
<aop:pointcut id="performance" expression="execution(* *.perform(..))" />
<aop:before method="" pointcut-ref="performance" />
<aop:before method="" pointcut="execution(* *.perform(..))" />
<aop:after-returning method="" pointcut="execution(* *.perform(..))" />
<aop:after-throwing method="" pointcut="execution(* *.perform(..))" />
</aop:aspect>
</aop:config>

3 利用Annotation

3.1 利用@Aspect將一個POJO類聲明為一個切面。

3.2 定義切點
@Pointcut("execution(* *.perform(..))")
public void performance(){}
通過@Pointcut定義的切點的名字就是它所註解的方法的名字,因此例子中的切點名字是
performance()。這里聲明的performance()方法實際聖只是一個標記,為@Pointcut提供附加的點,並不要求有實際意義。

3.3 定義通知
對要執行切面的方法,通過@Before("performance()"),@AfterReturning
("performance()")來定義通知。注意這里提供的切點名稱,是performance(),而不是performance

如果對上面的兩點不是很理解,也可以省略@Pointcut,而將AspectJ表達式直接定義在@Before等通知中,將上面的兩步合為一步,如@Before("execution(* *.perform(..))")

3.4 通知Spring創建代理
<aop:aspectj-autoproxy>
這實際上相當於聲明了一個,從而根據@Pointcut聲明的切點來自動代理匹配的bean實例

4 在Spring中結合進AspectJ
對於超出Spring AOP支持范圍的,可以採用這種方式。只需要在Spring中配置AspectJ的Class實例時讓Spring能夠獲得AspectJ類的實例就可以了,比如
<bean class="a_aspectj_class" factory-method="aspectOf">
<preperty .... />
</bean>

Ⅵ spring AOP 配置多個類的方法

expression="execution(* com.clouddrive.baseManage.service.impl..*.*(..)) " 改一下這里啊

Ⅶ spring中aop全註解時配置類怎麼寫

先說註解,使用註解配置Spring AOP總體分為兩步,第一步是在xml文件中聲明激活自動掃描組件功能,同時激活自動代理功能(同時在xml中添加一個UserService的普通服務層組件,來測試AOP的註解功能):

<?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/aop http://www.springframework.org/schema/aop/spring-aop-3.1.xsd
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-3.0.xsd">

<!-- 激活組件掃描功能,在包cn.ysh.studio.spring.aop及其子包下面自動掃描通過註解配置的組件 -->
<context:component-scan base-package="cn.ysh.studio.spring.aop"/>
<!-- 激活自動代理功能 -->
<aop:aspectj-autoproxy proxy-target-class="true"/>

<!-- 用戶服務對象 -->
<bean id="userService" class="cn.ysh.studio.spring.aop.service.UserService" />

</beans>

第二步是為Aspect切面類添加註解:

package cn.ysh.studio.spring.aop.aspect;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;

/**
* 系統服務組件Aspect切面Bean
* @author Shenghany
* @date 2013-5-28
*/
//聲明這是一個組件
@Component
//聲明這是一個切面Bean
@Aspect
public class ServiceAspect {

private final static Log log = LogFactory.getLog(ServiceAspect.class);

//配置切入點,該方法無方法體,主要為方便同類中其他方法使用此處配置的切入點
@Pointcut("execution(* cn.ysh.studio.spring.aop.service..*(..))")
public void aspect(){ }

/*
* 配置前置通知,使用在方法aspect()上注冊的切入點
* 同時接受JoinPoint切入點對象,可以沒有該參數
*/
@Before("aspect()")
public void before(JoinPoint joinPoint){
if(log.isInfoEnabled()){
log.info("before " + joinPoint);
}
}

//配置後置通知,使用在方法aspect()上注冊的切入點
@After("aspect()")
public void after(JoinPoint joinPoint){
if(log.isInfoEnabled()){
log.info("after " + joinPoint);
}
}

//配置環繞通知,使用在方法aspect()上注冊的切入點
@Around("aspect()")
public void around(JoinPoint joinPoint){
long start = System.currentTimeMillis();
try {
((ProceedingJoinPoint) joinPoint).proceed();
long end = System.currentTimeMillis();
if(log.isInfoEnabled()){
log.info("around " + joinPoint + " Use time : " + (end - start) + " ms!");
}
} catch (Throwable e) {
long end = System.currentTimeMillis();
if(log.isInfoEnabled()){
log.info("around " + joinPoint + " Use time : " + (end - start) + " ms with exception : " + e.getMessage());
}
}
}

//配置後置返回通知,使用在方法aspect()上注冊的切入點
@AfterReturning("aspect()")
public void afterReturn(JoinPoint joinPoint){
if(log.isInfoEnabled()){
log.info("afterReturn " + joinPoint);
}
}

//配置拋出異常後通知,使用在方法aspect()上注冊的切入點
@AfterThrowing(pointcut="aspect()", throwing="ex")
public void afterThrow(JoinPoint joinPoint, Exception ex){
if(log.isInfoEnabled()){
log.info("afterThrow " + joinPoint + " " + ex.getMessage());
}
}

}

測試代碼:

package cn.ysh.studio.spring.aop;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.;

import cn.ysh.studio.spring.aop.service.UserService;
import cn.ysh.studio.spring.mvc.bean.User;

/**
* Spring AOP測試
* @author Shenghany
* @date 2013-5-28
*/
public class Tester {

private final static Log log = LogFactory.getLog(Tester.class);

public static void main(String[] args) {
//啟動Spring容器
ApplicationContext context = new ("applicationContext.xml");
//獲取service組件
UserService service = (UserService) context.getBean("userService");
//以普通的方式調用UserService對象的三個方法
User user = service.get(1L);
service.save(user);
try {
service.delete(1L);
} catch (Exception e) {
if(log.isWarnEnabled()){
log.warn("Delete user : " + e.getMessage());
}
}
}
}

控制台輸出如下:

INFO [spring.aop.aspect.ServiceAspect:40] before execution(User cn.ysh.studio.spring.aop.service.UserService.get(long))
INFO [spring.aop.service.UserService:19] getUser method . . .
INFO [spring.aop.aspect.ServiceAspect:60] around execution(User cn.ysh.studio.spring.aop.service.UserService.get(long)) Use time : 42 ms!
INFO [spring.aop.aspect.ServiceAspect:48] after execution(User cn.ysh.studio.spring.aop.service.UserService.get(long))
INFO [spring.aop.aspect.ServiceAspect:74] afterReturn execution(User cn.ysh.studio.spring.aop.service.UserService.get(long))
INFO [spring.aop.aspect.ServiceAspect:40] before execution(void cn.ysh.studio.spring.aop.service.UserService.save(User))
INFO [spring.aop.service.UserService:26] saveUser method . . .
INFO [spring.aop.aspect.ServiceAspect:60] around execution(void cn.ysh.studio.spring.aop.service.UserService.save(User)) Use time : 2 ms!
INFO [spring.aop.aspect.ServiceAspect:48] after execution(void cn.ysh.studio.spring.aop.service.UserService.save(User))
INFO [spring.aop.aspect.ServiceAspect:74] afterReturn execution(void cn.ysh.studio.spring.aop.service.UserService.save(User))
INFO [spring.aop.aspect.ServiceAspect:40] before execution(boolean cn.ysh.studio.spring.aop.service.UserService.delete(long))
INFO [spring.aop.service.UserService:32] delete method . . .
INFO [spring.aop.aspect.ServiceAspect:65] around execution(boolean cn.ysh.studio.spring.aop.service.UserService.delete(long)) Use time : 5 ms with exception : spring aop ThrowAdvice演示
INFO [spring.aop.aspect.ServiceAspect:48] after execution(boolean cn.ysh.studio.spring.aop.service.UserService.delete(long))
INFO [spring.aop.aspect.ServiceAspect:74] afterReturn execution(boolean cn.ysh.studio.spring.aop.service.UserService.delete(long))
WARN [studio.spring.aop.Tester:32] Delete user : Null return value from advice does not match primitive return type for: public boolean cn.ysh.studio.spring.aop.service.UserService.delete(long) throws java.lang.Exception

可以看到,正如我們預期的那樣,雖然我們並沒有對UserSerivce類包括其調用方式做任何改變,但是Spring仍然攔截到了其中方法的調用,或許這正是AOP的魔力所在。

再簡單說一下xml配置方式,其實也一樣簡單:

<?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/aop http://www.springframework.org/schema/aop/spring-aop-3.1.xsd
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-3.0.xsd">


<!-- 系統服務組件的切面Bean -->
<bean id="serviceAspect" class="cn.ysh.studio.spring.aop.aspect.ServiceAspect"/>
<!-- AOP配置 -->
<aop:config>
<!-- 聲明一個切面,並注入切面Bean,相當於@Aspect -->
<aop:aspect id="simpleAspect" ref="serviceAspect">
<!-- 配置一個切入點,相當於@Pointcut -->
<aop:pointcut expression="execution(* cn.ysh.studio.spring.aop.service..*(..))" id="simplePointcut"/>
<!-- 配置通知,相當於@Before、@After、@AfterReturn、@Around、@AfterThrowing -->
<aop:before pointcut-ref="simplePointcut" method="before"/>
<aop:after pointcut-ref="simplePointcut" method="after"/>
<aop:after-returning pointcut-ref="simplePointcut" method="afterReturn"/>
<aop:after-throwing pointcut-ref="simplePointcut" method="afterThrow" throwing="ex"/>
</aop:aspect>
</aop:config>

</beans>

個人覺得不如註解靈活和強大,你可以不同意這個觀點,但是不知道如下的代碼會不會讓你的想法有所改善:

//配置前置通知,攔截返回值為cn.ysh.studio.spring.mvc.bean.User的方法
@Before("execution(cn.ysh.studio.spring.mvc.bean.User cn.ysh.studio.spring.aop.service..*(..))")
public void beforeReturnUser(JoinPoint joinPoint){
if(log.isInfoEnabled()){
log.info("beforeReturnUser " + joinPoint);
}
}

//配置前置通知,攔截參數為cn.ysh.studio.spring.mvc.bean.User的方法
@Before("execution(* cn.ysh.studio.spring.aop.service..*(cn.ysh.studio.spring.mvc.bean.User))")
public void beforeArgUser(JoinPoint joinPoint){
if(log.isInfoEnabled()){
log.info("beforeArgUser " + joinPoint);
}
}

//配置前置通知,攔截含有long類型參數的方法,並將參數值注入到當前方法的形參id中
@Before("aspect()&&args(id)")
public void beforeArgId(JoinPoint joinPoint, long id){
if(log.isInfoEnabled()){
log.info("beforeArgId " + joinPoint + " ID:" + id);
}
}

附上UserService的代碼(其實很簡單):

package cn.ysh.studio.spring.aop.service;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import cn.ysh.studio.spring.mvc.bean.User;

/**
* 用戶服務模型
* @author Shenghany
* @date 2013-5-28
*/
public class UserService {

private final static Log log = LogFactory.getLog(UserService.class);

public User get(long id){
if(log.isInfoEnabled()){
log.info("getUser method . . .");
}
return new User();
}

public void save(User user){
if(log.isInfoEnabled()){
log.info("saveUser method . . .");
}
}

public boolean delete(long id) throws Exception{
if(log.isInfoEnabled()){
log.info("delete method . . .");
throw new Exception("spring aop ThrowAdvice演示");
}
return false;
}

}

應該說學習Spring AOP有兩個難點,第一點在於理解AOP的理念和相關概念,第二點在於靈活掌握和使用切入點表達式。概念的理解通常不在一朝一夕,慢慢浸泡的時間長了,自然就明白了,下面我們簡單地介紹一下切入點表達式的配置規則吧。

通常情況下,表達式中使用」execution「就可以滿足大部分的要求。表達式格式如下:

execution(modifiers-pattern? ret-type-pattern declaring-type-pattern? name-pattern(param-pattern) throws-pattern?)

modifiers-pattern:方法的操作許可權

ret-type-pattern:返回值

declaring-type-pattern:方法所在的包

name-pattern:方法名

parm-pattern:參數名

throws-pattern:異常

其中,除ret-type-pattern和name-pattern之外,其他都是可選的。上例中,execution(* com.spring.service.*.*(..))表示com.spring.service包下,返回值為任意類型;方法名任意;參數不作限制的所有方法。

最後說一下通知參數

可以通過args來綁定參數,這樣就可以在通知(Advice)中訪問具體參數了。例如,<aop:aspect>配置如下:

<aop:config>
<aop:aspect id="TestAspect" ref="aspectBean">
<aop:pointcut id="businessService"
expression="execution(* com.spring.service.*.*(String,..)) and args(msg,..)" />
<aop:after pointcut-ref="businessService" method="doAfter"/>
</aop:aspect>
</aop:config>上面的代碼args(msg,..)是指將切入點方法上的第一個String類型參數添加到參數名為msg的通知的入參上,這樣就可以直接使用該參數啦。



熱點內容
網易蘋果游戲怎麼轉移到安卓 發布:2024-11-15 00:07:52 瀏覽:270
win7php環境搭建 發布:2024-11-15 00:06:55 瀏覽:17
erpjava 發布:2024-11-14 23:52:23 瀏覽:253
電腦版地平線四怎麼連上伺服器 發布:2024-11-14 23:46:42 瀏覽:472
ios怎麼變安卓 發布:2024-11-14 23:46:36 瀏覽:333
win7共享xp列印機拒絕訪問 發布:2024-11-14 23:45:29 瀏覽:750
引起資源配置失效的原因有哪些 發布:2024-11-14 23:35:22 瀏覽:15
c語言打字 發布:2024-11-14 23:11:06 瀏覽:893
存儲程序和程序控制的原理 發布:2024-11-14 22:53:23 瀏覽:323
python讀取json數據 發布:2024-11-14 22:51:52 瀏覽:931