0
点赞
收藏
分享

微信扫一扫

Spring AOP总结


Spring AOP总结
[code]
Spring AOP(Aspect Oriented Programming)

应用程序通常包含两种代码:一是核心业务代码,一是和业务关系不大的代码如日志、事物处理等。
AOP的思想就是使这两种代码分离,从而降低了两种代码的偶合性,达到了易于重用和维护的目的。
AOP和OOP:
在AOP里,每个关注点的实现并不知道是否有其他关注点关注它,这是AOP和OOP的主要区别,
在AOP里组合的流向是从横切关注点到主关注点,在OOP中组合流向是从主关注点到横切关注点。
AOP和OOP所关注的对象不同,AOP是OOP有益的补充,不是对立面。

AOP的3个关键概念:
1:切入点:(PiontCut)
连接点(Jion piont):是指程序运行中的某个阶段,如方法的调用、异常的抛出等。
PiontCut就是Jion piont点的集合,它是程序中需要注入的Advice的集合。指明Advice
在什么 条件下才被触发。
2:通知(Advice):
某个连接点采用的处理逻辑,也就是向连接点注入的代码。
3:Advisor
是PiontCut和Advice的配置器,它包含PiontCut和Advice,是把Advice注入到PiontCut位置的代码。


Spring 的3种切入点的实现:
1:静态切入点:
静态切入点只限于给定的方法和目标类。不考虑方法的参数。
2:动态切入点:
动态切入点不仅限于给定的方法和目标类,还可以指定方法的参数。
动态切入点有很大的性能损耗,一般很少使用。
3:自定义切入点:
正在发展


Spring 的通知:
1:Interception Around通知

Interception Around在Jion Point的前后执行。实现Interception Around通知要实现
MethodInterceptor接口,示例代码如下:

(1)Logger logger=Logger.getLogger(this.getClass().getName()); 


public Object invoke(MethodInvocation arg0) throws Throwable { 

 // TODO Auto-generated method stub 

 logger.log(Level.INFO,arg0.getArguments()[0]+"开始审核数据:"); 

 Object result=arg0.proceed(); 

 logger.log(Level.INFO,arg0.getArguments()[0]+"审核数据结束!"); 


 return result; 

} 


(2) 

 /* public class LoginInterceptor implements MethodInterceptor{ 

 public Object invoke(MenthodInvocation invocation) throws Throwable{ 

 System.out.println("开始审核数据"); 

 Object result = invocation.proceed(); 

 System.out.println("审核数据结束"); 

 return result; 

 } 

 }*/



2:Before通知
(1)通过log4j.properties实现

Logger logger=Logger.getLogger(this.getClass().getName()); 


public void before(Method arg0, Object[] arg1, Object arg2) 

 throws Throwable { 

 // TODO Auto-generated method stub 

 logger.log(Level.INFO,arg1[0]+"开始数据操作:"); 


} 

 (2): 

 Before通知在JiontPoint的前执行。实现Befored通知要实现 

 MethodBeforeAdvice接口,示例代码如下: 

 public class LoginBeforeAdvice implements MethodBeforeAdvice{ 

 public void before(Menthod m,Object [] atgs,Object target) throws Throwable{ 

 System.out.println("开始审核数据"); 

 } 

 }



3:After Return 通知

After Return通知在JiontPoint后执行。实现After Returnd通知要实现
AfterReturningAdvice接口,示例代码如下:

public class LoginAfterAdvice implements AfterReturningAdvice{ 

 public void afterReturning(Method m,Object [] atgs,Object target) throws Throwable{ 

 System.out.println("审核数据结束"); 

 } 

 }


4:Throw通知

(1)Logger logger=Logger.getLogger(this.getClass().getName()); 

public void afterThrowing(Method arg1, Object[] arg2,Object arg3,Throwable subclass ) throws Throwable{ 

 System.out.println(arg2[0]+"审核数据异常"); 

} 


 Throw通知在JiontPoint抛出异常时执行。实现Throw通知要实现 

 ThrowsAdvice接口,示例代码如下: 

 public class LoginThrowAdvice implements ThrowsAdvice{ 

 public void afterThrowing(Method arg1, RemoteException ex) throws Throwable{ 

 System.out.println("审核数据异常"); 

 } 

 }



5:Introduction 通知

Introduction通知在JiontPoint 调用完毕后执行。实现Introduction通知要实现
IntroductionAdvisor接口和IntroductionInterceptor接口。

用ProxyFactoryBean创建AOP代理
使用org.springfamework.aop.framework.ProxyFactoryBean是创建AOP代理的基本方式。

1:使用ProxyFactoryBean代理目标类中的所有方法(参考代码:workspace20070228\SpringAOP1)
示例代码:

<beans> 

 <bean id="log" class="logAround"/> 

 <bean id="logBefore" class="logBefore"/> 

 <bean id="logAfter" class="logAfter"/> 

 <bean id="logThrow" class="logThrow"/> 

 <bean id="timebook" class="TimeBook"/> 

 <!-设定代理类--> 

 <bean id="logProxy" class ="org.springframework.aop.framework.ProxyFactoryBean"> 

 <!--代理的是接口--> 

 <property name="proxyInterfaces"> 

 <value>TimeBookInterface</value> 

 </property> 

 <!--要代理的目标类--> 

 <property name="target"> 

 <ref bean="timebook"/> 

 </property> 

 <!--程序中的Advice--> 

 <property name="interceptorNames"> 

 <list> 

 <value>logBefore</value> 

 <value>logAfter</value> 

 <value>logThrow</value> 

 </list> 

 </property> 

 </bean> 

 </beans>


2:使用ProxyFactoryBean代理目标类中的指定方法

示例代码:

<beans> 

 <bean id="log" class="logAround"/> 

 <bean id="logBefore" class="logBefore"/> 

 <bean id="logAfter" class="logAfter"/> 

 <bean id="logThrow" class="logThrow"/> 

 <bean id="timebook" class="TimeBook"/> 

 <!--代理目标类的指定方法--> 

 <bean id ="logAdvisor" class="org.springframework.aop.support.RegexpMethodPointcutAdvisor"> 

 <property name="advice"> 

 <ref bean="log"/> 

 </property> 

 <!--指定要代理的方法--> 

 <property name="patterns"> 

 <value>.*doCheck.*</value> 

 </property> 

 </bean> 

 <!-设定代理类--> 

 <bean id="logProxy" class ="org.springframework.aop.framework.ProxyFactoryBean"> 


 <!--要代理的目标类--> 

 <property name="target"> 

 <ref bean="timebook"/> 

 </property> 

 <!--程序中的Advice--> 

 <property name="interceptorNames"> 

 <list> 

 <value>logAdvisor</value> 

 </list> 

 </property> 

 </bean> 

 </beans>


---------------------------------------------------------

正则表达式:
1:.表示可以匹配任何一个字符
2:[]表示只有[]里指定的字符才能匹配
3:*表示匹配次数
4:?表示可以匹配1或0次
5:\是正则表达式的连接符

---------------------------------------------------------------
Spring 中两种AOP代理方式
1:动态代理
动态代理是指代理的是接口,Spring默认的是动态代理
2:CGLIB代理

<beans> 

 <bean id="log" class="logAround"/> 

 <bean id="logBefore" class="logBefore"/> 

 <bean id="logAfter" class="logAfter"/> 

 <bean id="logThrow" class="logThrow"/> 

 <bean id="timebook" class="TimeBook"/> 

 <bean id="logProxy" class ="org.springframework.aop.framework.ProxyFactoryBean"> 

 <property name="proxyTargetClass"> 

 <value>true</value> 

 </property> 

 <property name="target"> 

 <ref bean="timebook"/> 

 </property> 

 <property name="interceptorNames"> 

 <list> 

 <value>logBefore</value> 

 <value>logAfter</value> 

 <value>logThrow</value> 

 </list> 

 </property> 

 </bean> 

 </beans>


-----------------------------------------------------------------------
Spring 中的自动代理方式

自动代理可以跨越多个类,不管哪个类中的方法只要符合要求都可以代理

<beans> 

<bean id="log" class="logAround"/> 

<bean id="logBefore" class="logBefore"/> 

<bean id="logAfter" class="logAfter"/> 

<bean id="logThrow" class="logThrow"/> 

<bean id="timebook" class="TimeBook"/> 

<bean id="timework" class="TimeWork"/> 

<!--使用自动代理--> 

<bean id="autoProxy" class ="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator"/> 

<bean id="logBeforAdvisor" class="org.springframework.aop.support.RegexpMethodPointcutAdvisor"> 

<property name="advice"> 

<ref bean="logBefore"/> 

</property> 

<property name="patterns"> 

<value>.*do.*</value> 

</property> 

</bean> 

</beans>


------------------------------------------------------------
Spring中的事务处理

事务处理是由多个步骤组成,这些步骤之间有一定的逻辑关系,作为一个整体的操作过程,所有的步骤必须同时成功或失败。
1:提交 当所有的操作步骤都被完整执行后,称为该事物被提交。
2:回滚 由于某个操作失败,导致所有的步骤都没被提交则事物必须回滚,回到事物执行前的状态。

事务的特性:
ACID:原子性(Atomicity)一致性(Consistency)隔离性(Isolation)持久性(Durablity)

Spring中的事务处理是基于动态AOP机制的实现。

1:编程式事务处理:

spring 提供的TransactionTemplate能够以编程的方式实现事务控制。

HelloADO.java: 

 private DataSource dataSource; 

 private PlatformTransactionManager transactionManager; 

 public int create(String msg){ 

 DefaultTransactionDefinition def = new DefaultTransactionDefinition(); 

 TransactionStatus status = transactionManager.getTransaction(def); 


 try{ 

 JdbcTemplate jt = new JdbcTemplate(dataSource); 

 int i=jt.update("insert into st(name,password) values('zz','zz')"); 

 return i; 

 }catch (Exception e){ 

 transactionManager.rollback(status); 

 return 0; 

 } 

 finally { 

 transactionManager.commit(status); 

 } 

 } 

 applicationContext.xml 


 <beans> 

 <bean id ="dataSource" class ="org.springframework.jdbc.datasource.DriverManagerDataSource"> 

 <property name="driverClassName"> 

 <value>com.mysql.jdbc.Driver</value> 

 </property> 

 <property name="url"> 

 <value>jdbc:mysql://localhost:3306/newdb</value> 

 </property> 

 <property name="username"> 

 <value>root</value> 

 </property> 

 <property name="password"> 

 <value>lxl</value> 

 </property> 

 </bean> 

 <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> 

 <property name="dataSource"> 

 <ref bean="dataSource"/> 

 </property> 

 </bean> 

 <bean id="helloDAO" class ="HelloDAO"> 

 <property name="dataSource"> 

 <ref bean="dataSource"/> 

 </property> 

 <property name="transactionManager"> 

 <ref bean="transactionManager"/> 

 </property> 

 </bean> 

 </beans>


2:声明式事务处理:

HelloADO.java:

public class HelloDAO { 

 private DataSource dataSource ; 

 private JdbcTemplate jdbcTemplate; 

 public void setDataSource(DataSource dataSource) { 

 this.dataSource = dataSource; 

 jdbcTemplate = new JdbcTemplate(dataSource); 

 } 

 public void create(String name){ 

 jdbcTemplate.update("insert into st(name,password)values('lxl','lxl')"); 

 } 

 } 

 applicationContext.xml 

 <beans> 

 <bean id ="dataSource" class ="org.springframework.jdbc.datasource.DriverManagerDataSource"> 

 <property name="driverClassName"> 

 <value>com.mysql.jdbc.Driver</value> 

 </property> 

 <property name="url"> 

 <value>jdbc:mysql://localhost:3306/newdb</value> 

 </property> 

 <property name="username"> 

 <value>root</value> 

 </property> 

 <property name="password"> 

 <value>lxl</value> 

 </property> 

 </bean> 

 <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> 

 <property name="dataSource"> 

 <ref bean="dataSource"/> 

 </property> 

 </bean> 

 <bean id="helloDAO" class ="HelloDAO"> 

 <property name="dataSource"> 

 <ref bean="dataSource"/> 

 </property> 

 </bean> 

 <!-- 声明式事务处理--> 

 <bean id="helloDAOProxy" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean"> 

 <property name="transactionManager"> 

 <ref bean="transactionManager"/> 

 </property> 

 <property name="target"> 

 <ref bean="helloDAO"/> 

 </property> 

 <property name="transactionAttributes"> 

 <props> 

 <!-- 对create方法进行事务管理,PROPAGATION_REQUIRED表示如果没有事务就新建一个事务--> 

 <prop key="create*">PROPAGATION_REQUIRED</prop> 

 </props> 

 </property> 

 </bean> 

 </beans> 

 [/code]

举报

相关推荐

0 条评论