`

第八章 aop xml配置实现

阅读更多
通过XML配置来实现Spring的AOP

首先还是提供一个服务层的接口与实现类:
接口:
public interface UserService {
public void create() throws Exception;
public void update() throws Exception;
public void delete() throws Exception;
}
实现类:
public class UserServiceImpl implements UserService {
@Override
public void create() throws Exception {
System.out.println("create方法调用");
}
@Override
public void delete() throws Exception {
System.out.println("delete方法调用");
}
@Override
public void update() throws Exception {
System.out.println("update方法调用");
}
}

接着,提供一个切面类,这个时候我们可以看到切面类只是一个普通的Java类
public class MyAspect {
public void beforeAdvice() {
System.out.println("前置通知");
}
public void afterAdvice() {
System.out.println("后置通知");
}
public void throwAdvice() {
System.out.println("异常通知");
}
public void finallyAdvice() {
System.out.println("最终通知");
}
public Object aroundAdvice(ProceedingJoinPoint pjp) throws Throwable {
System.out.println("环绕通知:进入方法");
Object retVal = pjp.proceed();
System.out.println("环绕通知:退出方法");
return retVal;
}
}

接着,我们开始XML的配置,
首先,将服务层,和切面类纳入Spring的管理范围,这里我们使用XML配置的方式(记住,切面类一定要纳入Spring的管理范围)
<?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/beans
           http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
           http://www.springframework.org/schema/context
           http://www.springframework.org/schema/context/spring-context-2.5.xsd          
           http://www.springframework.org/schema/aop
           http://www.springframework.org/schema/aop/spring-aop-2.5.xsd">
<bean id="userService" class="com.wdpc.aop.service.impl.UserServiceImpl" />
<bean id="myAspect" class="com.wdpc.aop.aspect.MyAspect" />
<aop:config>
<aop:aspect id="myAop" ref="myAspect">
<aop:pointcut id="mycut" expression="execution(* com.wdpc.aop..*.*(..))" />
<aop:before pointcut-ref="mycut" method="beforeAdvice" />
<aop:after-returning pointcut-ref="mycut" method="afterAdvice" />
<aop:after-throwing pointcut-ref="mycut" method="throwAdvice" />
<aop:after pointcut-ref="mycut" method="finallyAdvice" />
<aop:around pointcut-ref="mycut" method="aroundAdvice" />
</aop:aspect>
</aop:config>
</beans>
配置文件解释:
定义切面类: <bean id="myAspect" class="com.wdpc.aop.aspect.MyAspect" />
定义一个切面: <aop:aspect id="myAop" ref="myAspect">, 指定切面的实现类: ref="myAspect"
定义一个切入点:
<aop:pointcut id="mycut" expression="execution(* com.wdpc.aop..*.*(..))" />
前置通知:
<aop:before pointcut-ref="mycut" method="beforeAdvice" />, 引用切入点: pointcut-ref="mycut"

Test类:
public class Test {
public static void main(String[] args){
ApplicationContext ctx = new ClassPathXmlApplicationContext("beans.xml");
UserService userService = (UserService)ctx.getBean("userService");
try {
userService.create();
} catch (Exception e) {

}
}
}
可以改动UserServiceImpl类让create方法抛出一个异常,再看看执行的效果
@Override
public void create() throws Exception {
System.out.println("create方法调用");
throw new Exception();
}

切入点的简单研究:
 拦截返回类型为String类型的方法
在接口中添加一个方法,并在实现类中实现:
接口:
public String getUser() throws Exception;
实现类:
@Override
public String getUser() throws Exception {
System.out.println("getUser方法调用");
return "getUser";
}
修改切入点表达式:
<aop:pointcut id="mycut" expression="execution(java.lang.String com.wdpc.aop..*.*(..))" />
Test:
userService.getUser(); //被拦截
userService.create(); //不拦截

 拦截参数列表第一个为int类型的方法
在接口中添加一个方法,并在实现类中实现::
接口:
public String getUser() throws Exception;
public String getUser(int id) throws Exception;
public String getUser(int id, String name) throws Exception;

实现类:
@Override
public String getUser() throws Exception {
System.out.println("不带参的getUser方法调用");
return "getUser";
}

@Override
public String getUser(int id) throws Exception {
System.out.println("带参的getUser方法调用");
return "getUser";
}

@Override
public String getUser(int id, String name) throws Exception {
System.out.println("带丙个参数的getUser方法调用");
return "getUser";
}
可以看到方法重载了

修改切入点表达式:
<aop:pointcut id="mycut"
expression="execution(java.lang.String com.wdpc.aop..*.*(int,..))" />
注意这里: java.lang.Integer,.. 格式为:类型 逗号 两点

Test:
userService.getUser();
System.out.println("--------------");
userService.getUser(2);
System.out.println("--------------");
userService.getUser(2,"zhd");

 拦截返回类型为 非void 类型的方法
修改切入点表达式,注意非空的写法 :!void
<aop:pointcut id="mycut"
expression="execution(!void com.wdpc.aop..*.*(..))" />
Test:
userService.create();
System.out.println("--------------");
userService.update();
System.out.println("--------------");
userService.delete();
System.out.println("--------------");
userService.getUser();
System.out.println("--------------");
userService.getUser(2);
System.out.println("--------------");
userService.getUser(2,"zhd");

 基于XML配置的
在切面中 获取给方法传递的参数
这个时候就不能直接使用切入点的方式来编写了.
修改接口和实现类:
接口:
public void create(String name) throws Exception;
实现类:
@Override
public void create(String name) throws Exception {
System.out.println("create方法调用");
}
切面类:
public void beforeAdvice(String name) {
System.out.println("前置通知,获取的参数:" + name);
}
XML中的配置:
<aop:before pointcut="execution(* com.wdpc.aop..*.*(..)) and args(name)" method="beforeAdvice" arg-names="name" />
注意这里的写法:
pointcut="execution(* com.wdpc.aop..*.*(..)) and args(name)"
用的是pointcut,而不是pointcut-ref, 并且是and,而不是 &&
Test:
userService.create("zhd");

在切面中 获取方法的返回值(注意,只能在后置通知中获取返回值)
修改接口,实现类, 切面类
接口:
public String create(String name) throws Exception;
实现类:
@Override
public String create(String name) throws Exception {
System.out.println("create方法调用");
return "这里是create的返回值:" + name;
}
切面类:
public void beforeAdvice(String name) {
System.out.println("前置通知,获取的参数:" + name);
}
public void afterAdvice(String result) {
System.out.println("后置通知,接收的返回值:" + result);
}
XML配置:
<aop:before pointcut="execution(* com.wdpc.aop..*.*(..)) and args(name)" method="beforeAdvice" arg-names="name" />
<aop:after-returning pointcut="execution(* com.wdpc.aop..*.*(..))" returning="result" method="afterAdvice"  />


在切面中得到异常对象(只能在异常通知中获取)
修改实现类,让create 方法抛出一个异常
public String create(String name) throws Exception {
System.out.println("create方法调用");
throw new Exception("手动抛出的异常");
//return "这里是create的返回值:" + name;
}
return "这里是create的返回值:" + name; 这一句因为不可达,所以需要注释掉
修改切面类中的异常通知方法:
public void throwAdvice(Exception e) {
System.out.println("异常通知" + e);
}
XML配置:
<aop:after-throwing pointcut="execution(* com.wdpc.aop..*.*(..))" throwing="e" method="throwAdvice" />

Test:
public class Test {
public static void main(String[] args){
ApplicationContext ctx = new ClassPathXmlApplicationContext("beans.xml");
UserService userService = (UserService)ctx.getBean("userService");
try {
userService.create("zhd");
} catch (Exception e) {
}
}
}

前置通知接收参数时不能直接使用切入点的引用,
后置通知接收返回值是可以使用切入点的引用
异常通知接收异常对象是可以使用切入点的引用
<aop:config>
<aop:aspect id="mycut" ref="myAspect">
<aop:pointcut id="myPointcut" expression="execution(* com.wdpc.aop..*.*(..))" />
<aop:before pointcut-ref="myPointcut and args(name)"  method="beforeAdvice" arg-names="name"/>
<aop:after-returning pointcut-ref="myPointcut" returning="result"  method="afterAdvice" />
<aop:after-throwing pointcut-ref="myPointcut" throwing="e"  method="throwAdvice" />
<aop:after pointcut-ref="myPointcut"  method="finallyAdvice"/>
<aop:around pointcut-ref="myPointcut"  method="aroundAdvice"/>
</aop:aspect>
</aop:config>
红色部分为错误的语法.
分享到:
评论

相关推荐

    Spring+3.x企业应用开发实战光盘源码(全)

     第8章:介绍了Spring所提供的DAO封装层,这包括Spring DAO的异常体系、数据访问模板等内容。  第9章:介绍了Spring事务管理的工作机制,通过XML、注解等方式进行事务管理配置,同时还讲解了JTA事务配置知识。  ...

    陈开雄 Spring+3.x企业应用开发实战光盘源码.zip

     第8章:介绍了Spring所提供的DAO封装层,这包括Spring DAO的异常体系、数据访问模板等内容。  第9章:介绍了Spring事务管理的工作机制,通过XML、注解等方式进行事务管理配置,同时还讲解了JTA事务配置知识。 ...

    spring.net中文手册在线版

    第八章. 对象池 8.1.简介 8.2.接口和实现 第九章. Spring.NET杂记 9.1.简介 9.2.PathMatcher 9.2.1.通用规则 9.2.2.匹配文件名 9.2.3.匹配子目录 9.2.4.大小写需要考虑,斜线可以任意 第十章. 表达式求值 10.1.简介 ...

    Spring的学习笔记

    第八课:Spring AOP配置选项 21 一、 AOP配置annotation方式 21 (一) 搭建annotation开发环境 21 (二) aspectJ类库 22 (三) AOP的annotation实例 22 (四) AspectJ的专业术语 23 (五) 织入点语法 23 (六) Advice 24 ...

    spring2.5 学习笔记

    第八课:Spring AOP配置选项 21 一、 AOP配置annotation方式 21 (一) 搭建annotation开发环境 21 (二) aspectJ类库 22 (三) AOP的annotation实例 22 (四) AspectJ的专业术语 23 (五) 织入点语法 23 (六) Advice 24 ...

    Java/JavaEE 学习笔记

    三、struts-config.xml配置文件中主要的元素和属性.........286 四、RequestProccessor.....................287 五、Struts1的执行流程....................289 六、struts1的高级部分....................290 七、...

    J2EE学习笔记(J2ee初学者必备手册)

    三、struts-config.xml配置文件中主要的元素和属性.........286 四、RequestProccessor.....................287 五、Struts1的执行流程....................289 六、struts1的高级部分....................290 七、...

    Spring.3.x企业应用开发实战(完整版).part2

    第8章 Spring对DAO的支持 8.1 Spring的DAO理念 8.2 统一的异常体系 8.2.1 Spring的DAO异常体系 8.2.2 JDBC的异常转换器 8.2.3 其他持久技术的异常转换器 8.3 统一数据访问模板 8.3.1 使用模板和回调机制 8.3.2 ...

    Spring3.x企业应用开发实战(完整版) part1

    第8章 Spring对DAO的支持 8.1 Spring的DAO理念 8.2 统一的异常体系 8.2.1 Spring的DAO异常体系 8.2.2 JDBC的异常转换器 8.2.3 其他持久技术的异常转换器 8.3 统一数据访问模板 8.3.1 使用模板和回调机制 8.3.2 ...

    Java Web程序设计教程

    第8章hibernate框架基础 173 8.1orm简介 173 8.1.1应用orm的意义 173 8.1.2流行的orm框架 174 8.2准备hibernate运行环境 174 8.2.1下载与安装hibernate 175 8.2.2hibernate发布包介绍 175 8.3认识hibernate ...

    Java Web编程宝典-十年典藏版.pdf.part2(共2个)

    第8章 浅尝辄止 ——初识Struts2 8.1 本章学习任务 8.1.1 本章知识体系 8.1.2 实例开发任务. 8.2 Struts2概述 8.2.1 理解MVC原理 8.2.2 Struts2框架的产生 8.2.3 Struts2的结构体系 8.3 Struts2入门 8.3.1 Struts2的...

    J2EE应用开发详解

    104 第8章 Struts2框架 105 8.1 Web应用的发展 105 8.2 Struts2的起源和体系结构 106 8.3 Struts2核心部分详解 108 8.3.1 核心控制器FilterDispatcher 108 8.3.2 业务逻辑控制器Action 111 8.3.3 业务逻辑组件 116 ...

    spring in action英文版

     第8章 建立Web层  8.1 开始Spring MVC之旅  8.1.1 请求生命中的一天  8.1.2 配置DispatcherServlet  8.1.3 Spring MVC概述  8.2 将请求映射到控制器  8.2.1 将URL映射到Bean名称  8.2.2 ...

    java面试题

    2:Spring AOP:通过配置管理特性 3:Spring ORM:Spring框架集成了若干ORM框架 4:Spring DAO:打开关闭数据库连接 5:Spring WEB:为基于WEB服务的应用程序提供上下文服务 6:Spring Context:向Spring框架...

    低清版 大型门户网站是这样炼成的.pdf

    2.2.1 web.xml中struts 2的配置实现 54 2.2.2 struts 2属性配置文件struts.properties详解 55 2.2.3 struts 2核心配置文件struts.xml详解 57 2.3 struts 2应用开发实务 61 2.3.1 struts 2应用开发环境的搭建 62 ...

    JavaEE开发的颠覆者SpringBoot实战[完整版].part2

    第8 章 Spring Boot 的数据访问 233 8.1 引入Docker 237 8.1.1 Docker 的安装 238 8.1.2 Docker 常用命令及参数 242 8.1.3 下载本书所需的Docker 镜像 247 8.1.4 异常处理 247 8.2 Spring Data JPA 248 8.2.1 点睛...

    JavaEE开发的颠覆者SpringBoot实战[完整版].part3

    第8 章 Spring Boot 的数据访问 233 8.1 引入Docker 237 8.1.1 Docker 的安装 238 8.1.2 Docker 常用命令及参数 242 8.1.3 下载本书所需的Docker 镜像 247 8.1.4 异常处理 247 8.2 Spring Data JPA 248 8.2.1 点睛...

    JavaEE开发的颠覆者SpringBoot实战[完整版].part1

    第8 章 Spring Boot 的数据访问 233 8.1 引入Docker 237 8.1.1 Docker 的安装 238 8.1.2 Docker 常用命令及参数 242 8.1.3 下载本书所需的Docker 镜像 247 8.1.4 异常处理 247 8.2 Spring Data JPA 248 8.2.1 点睛...

Global site tag (gtag.js) - Google Analytics