锘??xml version="1.0" encoding="utf-8" standalone="yes"?>
]]>
聽NamespaceHandlerResolver錛堟帴鍙o級(jí)
聽聽聽 鐢盌efaultBeanDefinitionDocumentReader浣跨敤錛岀敤浜庡畾浣峃amespaceHandler錛屾寚瀹氱壒瀹氱殑鍛藉悕絀洪棿uri
聽聽 瀹炵幇綾伙細(xì)
聽聽 DefaultNamespaceHandlerResolver
聽聽
聽聽 閫氳繃map 淇濆瓨鎵鏈夌殑瀵瑰簲鍏崇郴
聽聽 榛樿浣跨敤spring.handlers鏂囦歡鏉ヤ繚瀛樻墍鏈夌殑handlers
聽聽 鍙互瀹氫箟鍏朵粬鐨刲ocation 濡傦細(xì)
聽聽 String location = "org/springframework/beans/factory/xml/support/customNamespace.properties";
聽聽 NamespaceHandlerResolver resolver = new DefaultNamespaceHandlerResolver(getClass().getClassLoader(), location);
聽聽
聽聽 NamespaceHandler錛堟帴鍙o級(jí)
聽聽聽
聽聽聽聽聽 鍩虹鎺ュ彛錛岀敤浜嶥efaultBeanDefinitionDocumentReader澶勭悊鑷畾涔夊懡鍚嶇┖闂淬?br />聽聽聽聽聽 鏂規(guī)硶錛?br />聽聽聽聽 聽聽聽 void init();
聽聽聽聽聽聽聽聽 鐢盌efaultBeanDefinitionDocumentReader璋冪敤鍦ㄦ瀯閫犲畬鍚庝絾鍦ㄨВ鏋愯嚜瀹氫箟鍏冪礌鍓嶃?br />聽
聽聽 聽聽聽聽聽 BeanDefinition parse(Element element, ParserContext parserContext);
聽聽聽聽聽聽聽聽 瑙f瀽鎸囧畾鐨勫厓绱犮?br />聽
聽聽 聽 聽 聽 BeanDefinitionHolder decorate(Node element,
聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽 BeanDefinitionHolder definition,
聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽 ParserContext parserContext);
聽聽聽聽聽聽聽聽 鎵ц鐩稿簲鐨勪慨楗般?br />
聽聽 瀹炵幇綾伙細(xì)
聽聽聽聽
聽聽聽聽 NamespaceHandlerSupport錛堟娊璞$被錛?/b>
聽聽
聽聽 涓昏鐨勪笁涓柟娉曪細(xì)
聽聽 protected final void registerBeanDefinitionDecorator(
聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽 String elementName,
聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽 BeanDefinitionDecorator decorator)
聽聽 娉ㄥ唽decorator錛岄氳繃element
聽
聽聽 protected final void registerBeanDefinitionDecoratorForAttribute(
聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽 String attributeName,
聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽 BeanDefinitionDecorator decorator)
聽聽聽 娉ㄥ唽decorator錛岄氳繃attr
聽聽
聽聽聽 protected final void registerBeanDefinitionParser(
聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽 String聽 elementName,
聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽 BeanDefinitionParser parser)
聽聽聽 娉ㄥ唽BeanDefinitionParser錛岄氳繃element
聽聽 瀹為檯鐨勬搷浣滅敱鍏蜂綋鐨凚eanDefinitionDecorator 鎴栬匓eanDefinitionParser 鎵ц
聽 BeanDefinitionDecorator(鎺ュ彛)
聽聽 瑁呴グ鐩稿叧鐨勮嚜瀹氫箟灞炴с?br />
聽聽聽聽 AbstractInterceptorDrivenBeanDefinitionDecorator
聽聽聽聽聽聽聽聽聽 鐢ㄤ簬娉ㄥ唽鐩稿簲鐨処nterceptor bean 瀹氫箟錛屼嬌鐢╝op浠g悊
聽 鍏朵粬綾伙細(xì)
聽聽聽 PluggableSchemaResolver錛岀敤浜庤嚜瀹氫箟鐩稿叧鐨剆chema,榛樿鐨剆chema 淇濆瓨浜巗pring.schemas鏂囦歡涓?br />
聽聽聽 鍙互閫氳繃瑕嗙洊resolveEntity鏂規(guī)硶鏉ヨ杞界浉搴旂殑鑷畾涔墄sd鏂囦歡
聽 涓昏鐨勬墽琛岀被錛?br />聽
聽 XmlBeanDefinitionReader
聽
聽聽聽 鐢ㄤ簬澶勭悊鐩稿簲鐨勮鍙栧伐浣滐紝鍏跺疄涓昏鐨勫伐浣滃媧劇粰BeanDefinitionDocumentReader
聽 瀹為檯鐨勭被錛屽氨浠嬬粛鍒拌繖錛屼笅涓鑺傞氳繃瀹炰緥鏉ヨ鏄庡浣曞畾涔夎嚜瀹氫箟xml 鍏冪礌
]]>
鑰冭檻涓嬮潰鐨勪緥瀛愶細(xì)(鐢?.x瀹炵幇錛?br /><bean id="myTxManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
聽聽聽 <property name="sessionFactory" ref="mySessionFactory"/>
聽 </bean>
聽 <bean id="myProductService" class="org.springframework.aop.framework.ProxyFactoryBean">
聽聽聽 <property name="proxyInterfaces" value="product.ProductService"/>
聽聽聽 <property name="target">
聽聽聽聽聽聽聽 <bean class="product.DefaultProductService">
聽聽聽聽聽聽聽聽聽聽聽 <property name="productDao" ref="myProductDao"/>
聽聽聽聽聽聽聽 </bean>
聽聽聽 </property>
聽聽聽 <property name="interceptorNames">
聽聽聽聽聽 <list>
聽聽聽聽聽聽聽 <value>myTxInterceptor</value> <!-- the transaction interceptor (configured elsewhere) -->
聽聽聽聽聽 </list>
聽聽聽 </property>
聽 </bean>
聽<bean id="myTxInterceptor"
class="org.springframework.transaction.interceptor.TransactionInterceptor">
<property name="transactionManager">
聽聽 <ref bean="myTransactionManager"/>
</property>
<property name="transactionAttributeSource">
聽 <value>
聽聽 product.ProductService.increasePrice*=PROPAGATION_REQUIRED
聽 product.ProductService.someOtherBusinessMethod=PROPAGATION_MANDATORY
聽 </value>
</property>
</bean>
鎴栬?br />
<bean id="myProductService"
class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
<property name="transactionManager">
<ref bean="myTransactionManager"/>
</property>
<property name="target">
<ref bean="myProductServiceTarget"/>
</property>
<property name="transactionAttributes">
<props>
<prop key="increasePrice*">PROPAGATION_REQUIRED</prop>
<prop key="someOtherBusinessMethod">PROPAGATION_MANDATORY</prop>
</props>
</property>
</bean>
褰撶劧錛岃繖闇瑕佹瘡涓湇鍔℃帴鍙i兘瑕佸0鏄庝竴涓簨鍔ean 錛岃繖姣旇緝楹葷儲(chǔ)錛屽綋鐒?dòng)灱宻pring 涔熸彁渚涗簡(jiǎn)鍙﹀涓縐嶈В鍐蟲柟妗?br />
閲囩敤BeanNameAutoProxyCreator 鑷姩浠g悊澹版槑鍏ュ彛鏉ュ叏灞澹版槑鎵鏈夌殑浜嬪姟銆?br /><bean id="matchAllWithPropReq"
聽聽聽聽聽聽聽聽聽class="org.springframework.transaction.interceptor.MatchAlwaysTransactionAttributeSource">
聽聽聽聽聽聽聽聽聽<property name="transactionAttribute"><value>PROPAGATION_REQUIRED</value></property>
</bean>
<bean id="matchAllTxInterceptor"
聽聽聽聽聽聽聽聽聽class="org.springframework.transaction.interceptor.TransactionInterceptor">
聽聽聽聽聽聽聽聽聽<property name="transactionManager"><ref bean="transactionManager"/></property>
聽聽聽聽聽聽聽聽聽<property name="transactionAttributeSource"><ref bean="matchAllWithPropReq"/></property>
</bean>
<bean id="autoProxyCreator"
聽聽聽聽聽聽聽聽聽class="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator">
聽聽聽聽聽聽聽聽聽<property name="interceptorNames">
聽聽聽聽聽聽聽聽聽聽聽聽<list>
聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽<idref local="matchAllTxInterceptor"/>
聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽<idref bean="hibInterceptor"/>
聽聽聽聽聽聽聽聽聽聽聽聽</list>
聽聽聽聽聽聽聽聽聽</property>
聽聽聽聽聽聽聽聽聽<property name="beanNames">
聽聽聽聽聽聽聽聽聽聽聽聽<list>
聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽<idref local="core-services-applicationControllerSevice"/>
聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽<idref local="core-services-deviceService"/>
聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽<idref local="core-services-authenticationService"/>
聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽<idref local="core-services-packagingMessageHandler"/>
聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽<idref local="core-services-sendEmail"/>
聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽<idref local="core-services-userService"/>
聽聽聽聽聽聽聽聽聽聽聽聽</list>
聽聽聽聽聽聽聽聽聽</property>
</bean>
list涓寘鍚簡(jiǎn)鎵鏈夐渶瑕佸疄鐜頒簨鍔$殑鏈嶅姟bean聽
聽spring 2.0甯︽潵鐨刟op鍙樺寲鍜宐ean xml schema鐨勫彉鍖栵紝浣垮緱浜嬪姟鐨勫鐞嗗彉寰楁洿鍔犵殑綆鍗?鍚宎op涓鏍鳳紝浜嬪姟涔熼噰鐢ㄤ袱縐嶆柟寮忔潵澶勭悊錛屼竴縐嶄富瑕佷負(fù)xml 澹版槑錛屽彟澶栫殑涓縐嶄篃灝辨槸娉ㄩ噴鐨勫紩鍏ャ?br />鍏堟潵鐪嬬涓縐嶆儏鍐碉細(xì)
<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"
聽聽聽聽聽聽 xmlns:tx="http://www.springframework.org/schema/tx"
聽聽聽聽聽聽 xsi:schemaLocation="
聽聽聽聽聽聽 http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
聽聽聽聽聽聽 http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd
聽聽聽聽聽聽 http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd">
聽 <!-- SessionFactory, DataSource, etc. omitted -->
聽 <bean id="myTxManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
聽聽聽 <property name="sessionFactory" ref="mySessionFactory"/>
聽 </bean>
聽
聽 <aop:config>
聽聽 <!-- 榪欏畾涔変簡(jiǎn)涓昏鐨勫垏闈紝涔熷氨鏄偅浜涙帴鍙e彲浠ヤ嬌鐢ㄤ簨鍔?榪欓噷鍙槸璇存墽琛?font color="#000000">ProductService鐨勬墍鏈夋柟娉?/font>-->
聽聽聽 <aop:pointcut id="productServiceMethods" expression="execution(* product.ProductService.*(..))"/>
聽聽聽 <aop:advisor advice-ref="txAdvice" pointcut-ref="productServiceMethods"/>
聽 </aop:config>
聽聽<!--涓昏鐨勪簨鍔?advice 澹版槑浜嬪姟鐨勭浉鍏沖睘鎬?->
聽 <tx:advice id="txAdvice" transaction-manager="myTxManager">
聽聽聽 <tx:attributes>
聽聽聽聽聽 <tx:method name="increasePrice*" propagation="REQUIRED"/>
聽聽聽聽聽 <tx:method name="someOtherBusinessMethod" propagation="REQUIRES_NEW"/>
聽聽聽聽聽 <tx:method name="*" propagation="SUPPORTS" read-only="true"/>
聽聽聽 </tx:attributes>
聽 </tx:advice>
聽 <bean id="myProductService" class="product.SimpleProductService">
聽聽聽 <property name="productDao" ref="myProductDao"/>
聽 </bean>
</beans>
絎簩縐嶆柟寮忥紝浣跨敤
@Transactional
娉ㄩ噴
@Transactional
public interface FooService {
聽聽聽 Foo getFoo(String fooName);
聽聽聽 Foo getFoo(String fooName, String barName);
聽聽聽 void insertFoo(Foo foo);
聽聽聽 void updateFoo(Foo foo);
}
xml 閰嶇疆
<!-- from the file 'context.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:aop="http://www.springframework.org/schema/aop"
聽聽聽聽聽聽 xmlns:tx="http://www.springframework.org/schema/tx"
聽聽聽聽聽聽 xsi:schemaLocation="
聽聽聽聽聽聽 http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
聽聽聽聽聽聽 http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd
聽聽聽聽聽聽 http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd">
聽
聽 <!-- this is the service object that we want to make transactional -->
聽 <bean id="fooService" class="x.y.service.DefaultFooService"/>
聽 <!-- enable the configuration of transactional behavior based on annotations -->
聽 <tx:annotation-driven/>
聽 <!-- a PlatformTransactionManager is still required -->
聽 <bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
聽聽聽 <!-- sourced from somewhere else -->
聽聽聽 <property name="dataSource" ref="dataSource"/>
聽 </bean>
聽
聽 <!-- other <bean/> definitions here -->
</beans>
public class DefaultFooService implements FooService {
聽聽聽 public Foo getFoo(String fooName) {
聽聽聽聽聽聽聽 // do something
聽聽聽 }
聽聽聽 // these settings have precedence
聽聽聽 @Transactional(readOnly = false, propagation = Propagation.REQUIRES_NEW)
聽聽聽 public void updateFoo(Foo foo) {
聽聽聽聽聽聽聽 // do something
聽聽聽 }
}
聽聽聽 private static Log log = LogFactory.getLog(Logger.class);
聽聽聽 public void entry(String message) {
聽聽聽聽聽聽聽 log.info(message);
聽聽聽 }
}
榪欓噷鍙槸綆鍗曠殑涓涓柟娉曪紝褰撶劧瀹為檯鎯呭喌鍙兘涓嶅悓銆?br />鐢變簬xml閰嶇疆闇瑕佷竴涓柟闈㈢殑瀹炵幇bean
鎵浠ュ垱寤轟竴涓畝鍗曠殑bean 錛?br />public class LogBean {
聽聽聽 private Logger logger = new Logger();
聽聽聽 public Object aroundLogCalls(ProceedingJoinPoint joinPoint) throws Throwable {
聽聽聽聽聽聽聽 logger.entry("before invoke method:"
聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽 + joinPoint.getSignature().getName());
聽聽聽聽聽聽聽 Object object = joinPoint.proceed();
聽聽聽聽聽聽聽 logger.entry("after invoke method:"
聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽 + joinPoint.getSignature().getName());
聽聽聽聽聽聽聽 return object;
聽聽聽 }
}
榪欓噷閲囧彇綆鍗曠殑around advice錛屽叾浠栫被鍨嬬殑advice 鍩烘湰涓婇兘宸笉澶?br />
褰撶劧鏈変簡(jiǎn)榪欎袱涓牳蹇?jī)鐨勬棩蹇椌c伙紝闇瑕佷竴涓祴璇曠被錛岀敤浜庢祴璇曘?br />public class TestBean {
聽聽聽 public void method1() {
聽聽聽聽聽聽聽 System.out.println("in method1");
聽聽聽 }
聽聽聽 public void method2() {
聽聽聽聽聽聽聽 System.out.println("in method2");
聽聽聽 }
}
榪欏氨鏄渶瑕佹祴璇曠殑綾諱簡(jiǎn)錛岄渶瑕佽褰曟棩蹇楃殑鏂規(guī)硶鍙湁涓や釜錛岃繖閲岀敤System.out.println錛屽彧鏄兂鏄劇ず鏂規(guī)硶鐨勮皟鐢ㄩ『搴忋?br />
鐒跺悗鍏抽敭鐨勫湪浜巟ml鐨勯厤緗簡(jiǎn)
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="聽xmlns:xsi="聽xmlns:aop="http://www.springframework.org/schema/aop"
聽xsi:schemaLocation="
http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/aophttp://www.springframework.org/schema/aop/spring-aop.xsd">
聽
聽<aop:config>
聽聽聽聽<!--聽聽expression 琛ㄧず瑕佹墽琛岀殑鍖歸厤琛ㄨ揪寮忥紝榪欓噷鍖歸厤鎵鏈夌殑public鏂規(guī)硶錛屼絾鏄幓闄ogger綾葷殑鎵鏈夋柟娉曪紝闃叉鏃犻檺璋冪敤-->
聽聽聽聽聽聽<aop:pointcut id="loggableCalls"
聽聽聽聽聽聽聽聽聽 expression="execution(public * *(..)) and !execution(* org.spring.test.aop.log.Logger.*(..))"/>
聽聽<aop:aspect id="logAspect" ref="logBean">
聽聽聽<aop:around pointcut-ref="loggableCalls" method="aroundLogCalls"/>
聽聽</aop:aspect>
聽
聽</aop:config>
聽<bean id="logBean" class="org.spring.test.aop.log.LogBean" />
聽<bean id="testBean" class="org.spring.test.aop.log.TestBean"/>
聽
</beans>
鐜板湪鍐欎竴涓祴璇曠被錛?br />
public class LogXmlTest extends RootTest {
聽聽聽 @Override
聽聽聽 protected String getBeanXml() {
聽聽聽聽聽聽聽 return "org/spring/test/aop/log/bean.xml";
聽聽聽 }
聽聽聽 public void testLog() {
聽聽聽聽聽聽聽 TestBean bean = (TestBean) ctx.getBean("testBean");
聽聽聽聽聽聽聽 bean.method1();
聽聽聽聽聽聽聽 bean.method2();
聽聽聽 }
}
public abstract class RootTest extends TestCase {
聽聽聽 protected ApplicationContext聽 ctx;
聽聽聽 protected Log log = LogFactory.getLog(getClass());
聽聽聽 protected RootTest() {
聽聽聽聽聽聽聽 ctx = new ClassPathXmlApplicationContext(getBeanXml());
聽聽聽 }
聽聽聽 protected abstract String getBeanXml();
}
鎵撳嵃鐨勬秷鎭涓嬶細(xì)
2006-09-17 11:08:28,203 INFO [org.spring.test.aop.log.Logger] - before invoke method:method1
in method1
2006-09-17 11:08:28,203 INFO [org.spring.test.aop.log.Logger] - after invoke method:method1
2006-09-17 11:08:28,218 INFO [org.spring.test.aop.log.Logger] - before invoke method:method2
in method2
2006-09-17 11:08:28,218 INFO [org.spring.test.aop.log.Logger] - after invoke method:method2
絎簩縐嶅疄鐜版柟寮忥紝閲囩敤娉ㄩ噴鏂瑰紡錛?br />
Logger 綾諱笉鍙?br />鍒涘緩涓涓狶ogAspect綾?br />@Aspect
public class LogAspect {
聽聽聽 private Logger logger = new Logger();
聽聽聽 @Pointcut("execution(public * *(..))")
聽聽聽 public void publicMethods() {
聽聽聽 }
聽聽聽 @Pointcut("execution(* org.spring.test.aop.log.Logger.*(..))")
聽聽聽 public void logObjectCalls() {
聽聽聽 }
聽聽聽 @Pointcut("publicMethods()&&!logObjectCalls()")
聽聽聽 public void loggableCalls() {
聽聽聽 }
聽聽聽 @Around("loggableCalls()")
聽聽聽 public Object aroundLogCalls(ProceedingJoinPoint joinPoint) throws Throwable {
聽聽聽聽聽聽聽 logger.entry("before invoke method:"
聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽 + joinPoint.getSignature().getName());
聽聽聽聽聽聽聽 Object object = joinPoint.proceed();
聽聽聽聽聽聽聽 logger.entry("after invoke method:"
聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽 + joinPoint.getSignature().getName());
聽聽聽聽聽聽聽 return object;
聽聽聽 }
}
閰嶇疆鏂囦歡灝辯畝鍗曞浜?br /><?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="聽xmlns:xsi="聽xmlns:aop="聽xsi:schemaLocation="
http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/aop聽
聽<aop:aspectj-autoproxy/>
聽
聽<!-- 鎴栬呬嬌鐢ㄤ互涓嬪畾涔?br />聽
聽
聽
聽<bean class="org.springframework.aop.aspectj.annotation.AnnotationAwareAspectJAutoProxyCreator" />
聽
聽-->
聽<bean id="logAspect" class="org.spring.test.aop.log.LogAspect"/>
聽<bean id="testBean" class="org.spring.test.aop.log.TestBean"/>
聽
</beans>
嫻嬭瘯綾伙細(xì)
璺熶笂闈㈢殑宸笉澶?br />鎶妜ml鏂囦歡鎹㈡帀灝辮
鎵撳嵃鐨勬柟寮忓樊涓嶅
涓漢榪樻槸姣旇緝鍠滄絎簩縐嶅疄鐜般?/p>
<aop:aspectj-autoproxy/>
鎴栬?br />鍦▁ml涓姞鍏?br /><bean class="org.springframework.aop.aspectj.annotation.AnnotationAwareAspectJAutoProxyCreator" />
澹版槑 aspect
<bean id="myAspect" class="org.xyz.NotVeryUsefulAspect">
聽聽 <!-- configure properties of aspect here as normal -->
</bean>
package org.xyz;
import org.aspectj.lang.annotation.Aspect;
@Aspect
public class NotVeryUsefulAspect {
}
澹版槑
pointcut
@Pointcut("execution(* transfer(..))")
public void transfer() {}
澹版槑
advice
Before advice:
@Before("com.xyz.myapp.SystemArchitecture.dataAccessOperation()")
聽 public void doAccessCheck() {
聽聽聽 // ...
聽 }
After returning advice:
@AfterReturning("com.xyz.myapp.SystemArchitecture.dataAccessOperation()")
聽 public void doAccessCheck() {
聽聽聽 // ...
聽 }
鎴栬?/span>
@AfterReturning(
pointcut="com.xyz.myapp.SystemArchitecture.dataAccessOperation()",
returning="retVal")
public void doAccessCheck(Object retVal) {
聽聽聽 // ...
聽 }
After throwing advice錛?o:p>
@AfterThrowing("SystemArchitecture.dataAccessOperation()")
聽 public void doRecoveryActions() {
聽聽聽 // ...
聽 }
鎴栬?/span>
@AfterThrowing(
聽聽聽 pointcut=" SystemArchitecture.dataAccessOperation()",
聽聽聽 throwing="ex")
聽 public void doRecoveryActions(DataAccessException ex) {
聽聽聽 // ...
聽 }
After (finally) advice錛?o:p>
@After("com.xyz.myapp.SystemArchitecture.dataAccessOperation()")
聽 public void doReleaseLock() {
聽聽聽 // ...
聽 }
Around advice錛?o:p>
@Around("com.xyz.myapp.SystemArchitecture.businessService()")
聽 public Object doBasicProfiling(
ProceedingJoinPoint
pjp) throws Throwable {
聽聽聽 // start stopwatch
聽聽聽 Object retVal = pjp.proceed();
聽聽聽 // stop stopwatch
聽聽聽 return retVal;
聽 }
Advice parameters錛?o:p>
@Before("com.xyz.myapp.SystemArchitecture.dataAccessOperation() &&" +
"args(account,..)"
)
public void validateAccount(Account account) {
聽 // ...
}
澹版槑鍙傛暟鍚嶇О錛?/span>
@Before(
聽聽 value="com.xyz.lib.Pointcuts.anyPublicMethod() && " +
聽聽聽聽聽聽聽聽 "@annotation(auditable)",
聽
聽argNames="auditable"
)
public void audit(Auditable auditable) {
聽 AuditCode code = auditable.value();
聽 // ...
}聽
Advice 鎺掑簭錛?o:p>
涓鑸互澹版槑鐨勬柟娉曟搴忎負(fù)鍏堝悗
涓嶅悓鐨?/span>
Advice
錛岄氳繃瀹炵幇
Ordered
鎺ュ彛錛屾潵鎺掑簭
鐢ㄤ簬寮曞叆鏂扮殑鎺ュ彛
@Aspect
public class UsageTracking {
聽
@DeclareParents(value="com.xzy.myapp.service.*+",
聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽 defaultImpl=DefaultUsageTracked.class)
聽 public static UsageTracked mixin;
聽
聽 @Before("com.xyz.myapp.SystemArchitecture.businessService() &&" +
聽聽聽聽聽聽聽聽聽 "this(usageTracked)")
聽 public void recordUsage(UsageTracked usageTracked) {
聽聽聽 usageTracked.incrementUseCount();
聽 }
聽
}
聽
<aop:config>
聽 <aop:aspect id="myAspect" ref="aBean">
聽聽聽 ...
聽 </aop:aspect>
</aop:config>
<bean id="aBean" class="...">
聽 ...
</bean>
鐢蟲槑pointcut
<aop:config>
聽 <aop:pointcut id="businessService"
聽聽聽聽聽聽聽 expression="execution(* com.xyz.myapp.service.*.*(..))"/>
</aop:config>
鐢蟲槑advice
Before advice錛?/span>
<aop:aspect id="beforeExample" ref="aBean">
聽聽聽 <aop:before
聽聽聽聽聽 pointcut-ref="dataAccessOperation"
聽聽聽聽聽 method="doAccessCheck"/>
</aop:aspect>
After returning advice:
<aop:aspect id="afterReturningExample" ref="aBean">
聽聽聽 <aop:after-returning
聽聽聽聽聽 pointcut-ref="dataAccessOperation"
聽聽聽聽聽 method="doAccessCheck"/>
聽聽聽聽聽聽聽聽聽
聽聽聽 ...
聽聽聽
</aop:aspect>
鎴栬呭甫鏈夎繑鍥炲弬鏁?/span>
<aop:aspect id="afterReturningExample" ref="aBean">
聽聽聽 <aop:after-returning
聽聽聽聽聽 pointcut-ref="dataAccessOperation"
聽聽聽聽 聽returning="retVal"
聽聽聽聽聽 method="doAccessCheck"/>
聽聽聽聽聽聽聽聽聽
聽聽聽 ...
聽聽聽
</aop:aspect>
After throwing advice錛?/span>
<aop:aspect id="afterThrowingExample" ref="aBean">
聽聽聽 <aop:after-throwing
聽聽聽聽聽 pointcut-ref="dataAccessOperation"
聽聽聽聽聽 method="doRecoveryActions"/>
聽聽聽聽聽聽聽聽聽
聽聽聽 ...
聽聽聽
</aop:aspect>
鎴栬呭甫鏈塼hrowing
<aop:aspect id="afterThrowingExample" ref="aBean">
聽聽聽 <aop:after-throwing
聽聽聽聽聽 pointcut-ref="dataAccessOperation"
聽聽聽聽聽 throwing="dataAccessEx"
聽聽聽聽聽 method="doRecoveryActions"/>
聽聽聽聽聽聽聽聽聽
聽聽聽 ...
聽聽聽
</aop:aspect>
After (finally) advice錛?/span>
<aop:aspect id="afterFinallyExample" ref="aBean">
聽聽聽 <aop:after
聽聽聽聽聽 pointcut-ref="dataAccessOperation"
聽聽聽聽聽 method="doReleaseLock"/>
聽聽聽聽聽聽聽聽聽
聽聽聽 ...
聽聽聽
</aop:aspect>
Around advice錛?/span>
<aop:aspect id="aroundExample" ref="aBean">
聽聽聽 <aop:around
聽聽聽聽聽 pointcut-ref="businessService"
聽聽聽聽聽 method="doBasicProfiling"/>
聽聽聽聽聽聽聽聽聽
聽聽聽 ...
聽聽聽
</aop:aspect>
Advice parameters錛?/span>
<aop:before
聽 pointcut="Pointcuts.anyPublicMethod() and @annotation(auditable)"
聽 method="audit"
聽聽arg-names="auditable"/>
瀵逛簬寮曞叆鎺ュ彛錛?a name="_Toc144432334">Introductions錛夛細(xì)
<aop:aspect id="usageTrackerAspect" ref="usageTracking">
聽 <aop:declare-parents
聽聽聽聽聽 types-matching="com.xzy.myapp.service.*+",
聽聽聽聽聽 implement-interface="UsageTracked"
聽聽聽聽聽 default-impl=" service.tracking.DefaultUsageTracked"/>
聽 <aop:before
聽聽聽 pointcut="com.xyz.myapp.SystemArchitecture.businessService()
聽聽聽聽聽聽聽聽聽聽聽聽聽 and this(usageTracked)"
聽聽聽 method="recordUsage"/>
</aop:aspect>