开源框架spring详解-----AOP的深刻理解
AOP的理解
1、AOP的概述
AOP是一种不同于OOP(面向对象编程)的编程模式,它不是OOP的替代,而是对OOP的一种有益补充。
2、spring AOP的原理
3、spring AOP的实现
在spring2.5中,常用的AOP实现方式有两种。第一种是基于xml配置文件方式的实现,第二种是基于注解方式的实现。
接下来,以具体的是理智讲解这两种方式的使用。
Java代码
package com.zxf.service;
/**
* 业务逻辑接口
* @author z_xiaofei168
*/
public interface AccountService {
public void save(String loginname, String password);
}
它的实现类
package com.zxf.service;
import com.zxf.dao.AccountDao;
/**
* AccountService的实现类
* @author z_xiaofei168
*/
public class AccountServiceImpl implements AccountService {
private AccountDao accountDao;
public AccountServiceImpl() {}
/** 带参数的构造方法 */
public AccountServiceImpl(AccountDao accountDao){
this.accountDao = accountDao;
}
public void save(String loginname, String password) {
accountDao.save(loginname, password);
throw new RuntimeException("故意抛出一个异常。。。。");
}
/** set方法 */
public void setAccountDao(AccountDao accountDao) {
this.accountDao = accountDao;
}
}
对于业务系统来说,AccountServiceImpl类就是目标实现类,它的业务方法,如save()方法的前后或代码会出现异常的地方都是AOP的连接点。
下面是日志服务类的代码:
Java代码
package com.zxf.aspect;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
/**
* 日志切面类
* @author z_xiaofei168
*/
public class LogAspect {
//任何通知方法都可以将第一个参数定义为 org.aspectj.lang.JoinPoint类型
public void before(JoinPoint call) {
//获取目标对象对应的类名
String className = call.getTarget().getClass().getName();
//获取目标对象上正在执行的方法名
String methodName = call.getSignature().getName();
System.out.println("前置通知:" + className + "类的" + methodName + "方法开始了");
}
public void afterReturn() {
System.out.println("后置通知:方法正常结束了");
}
public void after(){
System.out.println("最终通知:不管方法有没有正常执行完成,一定会返回的");
}
public void afterThrowing() {
System.out.println("异常抛出后通知:方法执行时出异常了");
}
//用来做环绕通知的方法可以第一个参数定义为org.aspectj.lang.ProceedingJoinPoint类型
public Object doAround(ProceedingJoinPoint call) throws Throwable {
Object result = null;
this.before(call);//相当于前置通知
try {
result = call.proceed();
this.afterReturn(); //相当于后置通知
} catch (Throwable e) {
this.afterThrowing(); //相当于异常抛出后通知
throw e;
}finally{
this.after(); //相当于最终通知
}
return result;
}
}
这个类属于业务服务类,如果用AOP的术语来说,它就是一个切面类,它定义了许多通知。Before()、afterReturn()、after()和afterThrowing()这些方法都是通知。
<1>.基于xml配置文件的AOP实现
这种方式在实现AOP时,有4个步骤。
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"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd>
<bean id="accountDaoImpl" class="com.zxf.dao.AccountDaoImpl"/>
<bean id="accountService" class="com.zxf.service.AccountServiceImpl">
<property name=" accountDaoImpl " ref=" accountDaoImpl "/>
</bean>
<!-- 日志切面类 -->
<bean id="logAspectBean" class="com.zxf.aspect.LogAspect"/>
<!-- 第1步: AOP的配置 -->
<aop:config>
<!-- 第2步:配置一个切面 -->
<aop:aspect id="logAspect" ref="logAspectBean">
<!-- 第3步:定义切入点,指定切入点表达式 -->
<aop:pointcut id="allMethod"
expression="execution(* com.zxf.service.*.*(..))"/>
<!-- 第4步:应用前置通知 -->
<aop:before method="before" pointcut-ref="allMethod" />
<!-- 第4步:应用后置通知 -->
<aop:after-returning method="afterReturn" pointcut-ref="allMethod"/>
<!-- 第4步:应用最终通知 -->
<aop:after method="after" pointcut-ref="allMethod"/>
<!-- 第4步:应用抛出异常后通知 -->
<aop:after-throwing method="afterThrowing" pointcut-ref="allMethod"/>
<!-- 第4步:应用环绕通知 -->
<!--
<aop:around method="doAround" pointcut-ref="allMethod" />
-->
</aop:aspect>
</aop:config>
</beans>
上述配置针对切入点应用了前置、后置、最终,以及抛出异常后通知。这样在测试执行AccountServiceImpl类的save()方法时,控制台会有如下结果输出。
前置通知:com.zxf.service.AccountServiceImpl类的save方法开始了。
针对MySQL的AccountDao实现中的save()方法。
后置通知:方法正常结束了。
最终通知:不管方法有没有正常执行完成,一定会返回的。
<2>基于注解的AOP的实现
首先创建一个用来作为切面的类LogAnnotationAspect,同时把这个类配置在spring的配置文件中。
在spring2.0以后引入了JDK5.0的注解Annotation的支持,提供了对AspectJ基于注解的切面的支持,从而 更进一步地简化AOP的配置。具体的步骤有两步。
Spring的配置文件是如下的配置:
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"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd>
<bean id="accountDao" class="com.zxf.dao.AccountDaoImpl"/>
<bean id="accountService" class="com.zxf.service.AccountServiceImpl">
<property name="accountDao" ref="accountDao"/>
</bean>
<!-- 把切面类交由Spring容器来管理 -->
<bean id="logAspectBean" class="com.zxf.aspect.LogAnnotationAspect"/>
<!-- 启用spring对AspectJ注解的支持 -->
<aop:aspectj-autoproxy/>
</beans>
这是那个切面的类LogAnnotationAspect
Java代码
package com.zxf.aspect;
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.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
/**
* 日志切面类
*/
@Aspect //定义切面类
public class LogAnnotationAspect {
@SuppressWarnings("unused")
//定义切入点
@Pointcut("execution(* com.zxf.service.*.*(..))")
private void allMethod(){}
//针对指定的切入点表达式选择的切入点应用前置通知
@Before("execution(* com. zxf.service.*.*(..))")
public void before(JoinPoint call) {
String className = call.getTarget().getClass().getName();
String methodName = call.getSignature().getName();
System.out.println("【注解-前置通知】:" + className + "类的"
+ methodName + "方法开始了");
}
//访问命名切入点来应用后置通知
@AfterReturning("allMethod()")
public void afterReturn() {
System.out.println("【注解-后置通知】:方法正常结束了");
}
//应用最终通知
@After("allMethod()")
public void after(){
System.out.println("【注解-最终通知】:不管方法有没有正常执行完成,"
+ "一定会返回的");
}
//应用异常抛出后通知
@AfterThrowing("allMethod()")
public void afterThrowing() {
System.out.println("【注解-异常抛出后通知】:方法执行时出异常了");
}
//应用周围通知
//@Around("allMethod()")
public Object doAround(ProceedingJoinPoint call) throws Throwable{
Object result = null;
this.before(call);//相当于前置通知
try {
result = call.proceed();
this.afterReturn(); //相当于后置通知
} catch (Throwable e) {
this.afterThrowing(); //相当于异常抛出后通知
throw e;
}finally{
this.after(); //相当于最终通知
}
return result;
}
}
备注:输出结果和前面的一样。
AOP的理解
1、AOP的概述
AOP是一种不同于OOP(面向对象编程)的编程模式,它不是OOP的替代,而是对OOP的一种有益补充。
2、spring AOP的原理
3、spring AOP的实现
在spring2.5中,常用的AOP实现方式有两种。第一种是基于xml配置文件方式的实现,第二种是基于注解方式的实现。
接下来,以具体的是理智讲解这两种方式的使用。
Java代码
package com.zxf.service;
/**
* 业务逻辑接口
* @author z_xiaofei168
*/
public interface AccountService {
public void save(String loginname, String password);
}
它的实现类
package com.zxf.service;
import com.zxf.dao.AccountDao;
/**
* AccountService的实现类
* @author z_xiaofei168
*/
public class AccountServiceImpl implements AccountService {
private AccountDao accountDao;
public AccountServiceImpl() {}
/** 带参数的构造方法 */
public AccountServiceImpl(AccountDao accountDao){
this.accountDao = accountDao;
}
public void save(String loginname, String password) {
accountDao.save(loginname, password);
throw new RuntimeException("故意抛出一个异常。。。。");
}
/** set方法 */
public void setAccountDao(AccountDao accountDao) {
this.accountDao = accountDao;
}
}
对于业务系统来说,AccountServiceImpl类就是目标实现类,它的业务方法,如save()方法的前后或代码会出现异常的地方都是AOP的连接点。
下面是日志服务类的代码:
Java代码
package com.zxf.aspect;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
/**
* 日志切面类
* @author z_xiaofei168
*/
public class LogAspect {
//任何通知方法都可以将第一个参数定义为 org.aspectj.lang.JoinPoint类型
public void before(JoinPoint call) {
//获取目标对象对应的类名
String className = call.getTarget().getClass().getName();
//获取目标对象上正在执行的方法名
String methodName = call.getSignature().getName();
System.out.println("前置通知:" + className + "类的" + methodName + "方法开始了");
}
public void afterReturn() {
System.out.println("后置通知:方法正常结束了");
}
public void after(){
System.out.println("最终通知:不管方法有没有正常执行完成,一定会返回的");
}
public void afterThrowing() {
System.out.println("异常抛出后通知:方法执行时出异常了");
}
//用来做环绕通知的方法可以第一个参数定义为org.aspectj.lang.ProceedingJoinPoint类型
public Object doAround(ProceedingJoinPoint call) throws Throwable {
Object result = null;
this.before(call);//相当于前置通知
try {
result = call.proceed();
this.afterReturn(); //相当于后置通知
} catch (Throwable e) {
this.afterThrowing(); //相当于异常抛出后通知
throw e;
}finally{
this.after(); //相当于最终通知
}
return result;
}
}
这个类属于业务服务类,如果用AOP的术语来说,它就是一个切面类,它定义了许多通知。Before()、afterReturn()、after()和afterThrowing()这些方法都是通知。
<1>.基于xml配置文件的AOP实现
这种方式在实现AOP时,有4个步骤。
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"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd>
<bean id="accountDaoImpl" class="com.zxf.dao.AccountDaoImpl"/>
<bean id="accountService" class="com.zxf.service.AccountServiceImpl">
<property name=" accountDaoImpl " ref=" accountDaoImpl "/>
</bean>
<!-- 日志切面类 -->
<bean id="logAspectBean" class="com.zxf.aspect.LogAspect"/>
<!-- 第1步: AOP的配置 -->
<aop:config>
<!-- 第2步:配置一个切面 -->
<aop:aspect id="logAspect" ref="logAspectBean">
<!-- 第3步:定义切入点,指定切入点表达式 -->
<aop:pointcut id="allMethod"
expression="execution(* com.zxf.service.*.*(..))"/>
<!-- 第4步:应用前置通知 -->
<aop:before method="before" pointcut-ref="allMethod" />
<!-- 第4步:应用后置通知 -->
<aop:after-returning method="afterReturn" pointcut-ref="allMethod"/>
<!-- 第4步:应用最终通知 -->
<aop:after method="after" pointcut-ref="allMethod"/>
<!-- 第4步:应用抛出异常后通知 -->
<aop:after-throwing method="afterThrowing" pointcut-ref="allMethod"/>
<!-- 第4步:应用环绕通知 -->
<!--
<aop:around method="doAround" pointcut-ref="allMethod" />
-->
</aop:aspect>
</aop:config>
</beans>
上述配置针对切入点应用了前置、后置、最终,以及抛出异常后通知。这样在测试执行AccountServiceImpl类的save()方法时,控制台会有如下结果输出。
前置通知:com.zxf.service.AccountServiceImpl类的save方法开始了。
针对MySQL的AccountDao实现中的save()方法。
后置通知:方法正常结束了。
最终通知:不管方法有没有正常执行完成,一定会返回的。
<2>基于注解的AOP的实现
首先创建一个用来作为切面的类LogAnnotationAspect,同时把这个类配置在spring的配置文件中。
在spring2.0以后引入了JDK5.0的注解Annotation的支持,提供了对AspectJ基于注解的切面的支持,从而 更进一步地简化AOP的配置。具体的步骤有两步。
Spring的配置文件是如下的配置:
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"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd>
<bean id="accountDao" class="com.zxf.dao.AccountDaoImpl"/>
<bean id="accountService" class="com.zxf.service.AccountServiceImpl">
<property name="accountDao" ref="accountDao"/>
</bean>
<!-- 把切面类交由Spring容器来管理 -->
<bean id="logAspectBean" class="com.zxf.aspect.LogAnnotationAspect"/>
<!-- 启用spring对AspectJ注解的支持 -->
<aop:aspectj-autoproxy/>
</beans>
这是那个切面的类LogAnnotationAspect
Java代码
package com.zxf.aspect;
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.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
/**
* 日志切面类
*/
@Aspect //定义切面类
public class LogAnnotationAspect {
@SuppressWarnings("unused")
//定义切入点
@Pointcut("execution(* com.zxf.service.*.*(..))")
private void allMethod(){}
//针对指定的切入点表达式选择的切入点应用前置通知
@Before("execution(* com. zxf.service.*.*(..))")
public void before(JoinPoint call) {
String className = call.getTarget().getClass().getName();
String methodName = call.getSignature().getName();
System.out.println("【注解-前置通知】:" + className + "类的"
+ methodName + "方法开始了");
}
//访问命名切入点来应用后置通知
@AfterReturning("allMethod()")
public void afterReturn() {
System.out.println("【注解-后置通知】:方法正常结束了");
}
//应用最终通知
@After("allMethod()")
public void after(){
System.out.println("【注解-最终通知】:不管方法有没有正常执行完成,"
+ "一定会返回的");
}
//应用异常抛出后通知
@AfterThrowing("allMethod()")
public void afterThrowing() {
System.out.println("【注解-异常抛出后通知】:方法执行时出异常了");
}
//应用周围通知
//@Around("allMethod()")
public Object doAround(ProceedingJoinPoint call) throws Throwable{
Object result = null;
this.before(call);//相当于前置通知
try {
result = call.proceed();
this.afterReturn(); //相当于后置通知
} catch (Throwable e) {
this.afterThrowing(); //相当于异常抛出后通知
throw e;
}finally{
this.after(); //相当于最终通知
}
return result;
}
}
备注:输出结果和前面的一样。
- Hibernate缓存深入详解.rar (1.9 MB)
- 下载次数: 5
发表评论
-
菜鸟 Spring 源码解读 推荐流程
2012-01-11 09:18 5053Spring源代码解析(一):IOC容器:http://www ... -
深入剖析Classloader(一)--类的主动使用与被动使用
2011-12-27 22:13 1053我们知道java运行的是这样的,首先java编译器将我们的源代 ... -
Java中连接字符串时是使用+号还是使用StringBuilder?
2011-12-26 14:04 886字符串是Java程序中最常用的一种数据结构之一。在Java中的 ... -
转一篇有关Java的内存泄露的文章(受益哦)
2011-07-20 09:28 7331 引言 Java的一个 ... -
Tomcat内存溢出的原因
2011-07-19 09:41 698Tomcat内存溢出的原因 在生产环境中tomcat内 ... -
深入研究java.lang.ThreadLocal类
2011-07-13 09:39 655一、概述 ThreadLocal是什么呢?其实Thread ... -
jboss中实现跨war包session同步
2011-06-12 23:28 1231跨war包session同步解决方 ... -
struts2核心工作流程与工作原理
2011-05-26 15:35 12491. Struts2架构图 这是S truts2官方站点提供的 ... -
Spring注入方式及用到的注解 -----@Component,@Service,@Controller,@Repository
2011-05-26 15:04 1188注入方式: 把DAO实现 ... -
Java中的native关键字浅析(Java Native Interface)
2011-05-21 23:13 698JNI是Java Native Interface的 ... -
Volatile 变量
2011-04-26 17:01 597Java 语言中的 volatile 变量可以被看作是一种 “ ... -
Java对象的强、软、弱和虚引用
2011-04-26 16:04 5931.Java对象的强、软、 ... -
Web 应用程序常见漏洞 CSRF 的入侵检测与防范
2011-04-23 15:00 1066简介: 互联网的安全问题一直存在,并且在可预见的未来中没有消弭 ... -
详解XSS跨站脚本攻击
2011-04-23 13:46 1107一、什么是XSS攻击 XSS ... -
CSRF攻击原理解析
2011-04-22 10:29 12420×00. 前言 在Web程序中 ... -
selenium 初步体检之富文本框操作
2011-04-20 20:10 1486public class LoginTest extends ... -
webx
2011-03-05 17:54 960webx 学习笔记。 -
Java读带有BOM的UTF-8文件乱码解决方法
2011-03-02 11:12 2384Java default io reader does not ... -
java sftp tools
2011-02-24 13:30 1484import java.io.File; import jav ... -
HtmlUnit
2010-10-18 22:27 1625IntroductionThe dependencies pa ...
相关推荐
Spring5 框架 ---- AOP ---- 代码 Spring5 框架 ---- AOP ---- 代码 Spring5 框架 ---- AOP ---- 代码 Spring5 框架 ---- AOP ---- 代码 Spring5 框架 ---- AOP ---- 代码 Spring5 框架 ---- AOP ---- 代码 Spring5 ...
spring-aop-1.1.1.jar spring-aop-1.2.6.jar spring-aop-1.2.9.jar spring-aop-2.0.2.jar spring-aop-2.0.6.jar spring-aop-2.0.7.jar spring-aop-2.0.8.jar spring-aop-2.0.jar spring-aop-2.5.1.jar spring-aop-...
开发工具 spring-aop-4.3.6.RELEASE开发工具 spring-aop-4.3.6.RELEASE开发工具 spring-aop-4.3.6.RELEASE开发工具 spring-aop-4.3.6.RELEASE开发工具 spring-aop-4.3.6.RELEASE开发工具 spring-aop-4.3.6.RELEASE...
赠送jar包:spring-aop-5.2.0.RELEASE.jar; 赠送原API文档:spring-aop-5.2.0.RELEASE-javadoc.jar; 赠送源代码:spring-aop-5.2.0.RELEASE-sources.jar; 赠送Maven依赖信息文件:spring-aop-5.2.0.RELEASE.pom;...
赠送jar包:spring-aop-5.0.8.RELEASE.jar; 赠送原API文档:spring-aop-5.0.8.RELEASE-javadoc.jar; 赠送源代码:spring-aop-5.0.8.RELEASE-sources.jar; 赠送Maven依赖信息文件:spring-aop-5.0.8.RELEASE.pom;...
赠送jar包:spring-aop-5.3.10.jar; 赠送原API文档:spring-aop-5.3.10-javadoc.jar; 赠送源代码:spring-aop-5.3.10-sources.jar; 赠送Maven依赖信息文件:spring-aop-5.3.10.pom; 包含翻译后的API文档:spring...
aopalliance.jar、spring-aop-4.1.6.RELEASE.jar、spring-aspects-4.1.6.RELEASE.jar
spring-aop-3.2.5.RELEASE.jar
赠送jar包:spring-aop-5.3.12.jar; 赠送原API文档:spring-aop-5.3.12-javadoc.jar; 赠送源代码:spring-aop-5.3.12-sources.jar; 赠送Maven依赖信息文件:spring-aop-5.3.12.pom; 包含翻译后的API文档:spring...
赠送jar包:spring-aop-5.0.10.RELEASE.jar; 赠送原API文档:spring-aop-5.0.10.RELEASE-javadoc.jar; 赠送源代码:spring-aop-5.0.10.RELEASE-sources.jar; 赠送Maven依赖信息文件:spring-aop-5.0.10.RELEASE....
赠送jar包:spring-aop-5.1.3.RELEASE.jar; 赠送原API文档:spring-aop-5.1.3.RELEASE-javadoc.jar; 赠送源代码:spring-aop-5.1.3.RELEASE-sources.jar; 赠送Maven依赖信息文件:spring-aop-5.1.3.RELEASE.pom;...
spring-aop-4.0.4.RELEASE 的jar包,亲测可用。。。。
spring-**core**-4.3.6.RELEASE.jar :包含spring框架基本的核心工具类,spring其他组件都要用到这个包里的类,其他组件的基本核心 spring-**beans**-4.3.6.RELEASE.jar:所有应用都要用到的jar包,它包含访问配置...
spring-aop-5.0.4.RELEASE.jar。
spring-aop-2.0.8.jar
spring-aop-3.2.0.RELEASE.jar,一个Spring中AOP的jar包
赠送jar包:spring-aop-4.2.2.RELEASE.jar; 赠送原API文档:spring-aop-4.2.2.RELEASE-javadoc.jar; 赠送源代码:spring-aop-4.2.2.RELEASE-sources.jar; 赠送Maven依赖信息文件:spring-aop-4.2.2.RELEASE.pom;...
赠送jar包:spring-aop-4.3.20.RELEASE.jar 赠送原API文档:spring-aop-4.3.20.RELEASE-javadoc.jar 赠送源代码:spring-aop-4.3.20.RELEASE-sources.jar 包含翻译后的API文档:spring-aop-4.3.20.RELEASE-...
赠送jar包:spring-aop-5.3.15.jar; 赠送原API文档:spring-aop-5.3.15-javadoc.jar; 赠送源代码:spring-aop-5.3.15-sources.jar; 赠送Maven依赖信息文件:spring-aop-5.3.15.pom; 包含翻译后的API文档:spring...