Java基础-SSM之Spring的AOP编程

                                    作者:尹正杰

版权声明:原创作品,谢绝转载!否则将追究法律责任。

    Spring的本质说白了就是动态代理,接下来我们会体验AOP的用法。它是对OOP的增强,适用于系统级功能。

 一.MethodBeforeAdvice接口的应用

1>.引入新的依赖

 <?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion> <groupId>cn.org.yinzhengjie</groupId>
<artifactId>MySpring</artifactId>
<version>1.0-SNAPSHOT</version> <dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-support</artifactId>
<version>4.3.5.RELEASE</version>
</dependency> <dependency>
<groupId>aopalliance</groupId>
<artifactId>aopalliance</artifactId>
<version>1.0</version>
</dependency>
</dependencies> </project>

2>.定义通知类

 /*
@author :yinzhengjie
Blog:http://www.cnblogs.com/yinzhengjie/tag/Java%E5%9F%BA%E7%A1%80/
EMAIL:y1053419035@qq.com
*/
package cn.org.yinzhengjie.spring.aop.advice; import org.springframework.aop.MethodBeforeAdvice; import java.lang.reflect.Method; /**
* 前置通知
*/
public class MyMethodBeforeAdvice implements MethodBeforeAdvice {
public void before(Method method, Object[] args, Object target) throws Throwable {
String mname = method.getName() ;
System.out.printf("当前处理的对象 : %s\n调用对象的方法 : %s\n调用参数 : %s\n" , target.toString(),mname.toString(),args.toString());
System.out.println("============= MyMethodBeforeAdvice代码执行完毕 =============");
}
}

3>.编写实现WelcomeService和WelcomeService2两个接口的类

 /*
@author :yinzhengjie
Blog:http://www.cnblogs.com/yinzhengjie/tag/Java%E5%9F%BA%E7%A1%80/
EMAIL:y1053419035@qq.com
*/
package cn.org.yinzhengjie.spring.aop.advice; public interface WelcomeService {
public abstract void sayHello();
}

WelcomeService.java 文件内容

 /*
@author :yinzhengjie
Blog:http://www.cnblogs.com/yinzhengjie/tag/Java%E5%9F%BA%E7%A1%80/
EMAIL:y1053419035@qq.com
*/
package cn.org.yinzhengjie.spring.aop.advice; public interface WelcomeService2 {
public abstract void sayHello2();
}

WelcomeService2.java 文件内容

 /*
@author :yinzhengjie
Blog:http://www.cnblogs.com/yinzhengjie/tag/Java%E5%9F%BA%E7%A1%80/
EMAIL:y1053419035@qq.com
*/
package cn.org.yinzhengjie.spring.aop.advice; public class WelcomeServiceImpl implements WelcomeService,WelcomeService2{
private String name ; public String getName() {
return name;
} public void setName(String name) {
this.name = name;
} public void sayHello() {
System.out.println(name);
} public void sayHello2() {
System.out.println("Hello Wold");
}
}

4>.编写Spring的配置文件

 <?xml version="1.0"?>
<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:context="http://www.springframework.org/schema/context"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.3.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-4.3.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-4.3.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-4.3.xsd">
<!-- 前置通知 -->
<bean id="beforeAdvice" class="cn.org.yinzhengjie.spring.aop.advice.MyMethodBeforeAdvice" /> <!-- 目标对象 -->
<bean id="wsTarget" class="cn.org.yinzhengjie.spring.aop.advice.WelcomeServiceImpl">
<property name="name" value="I'm yinzhengjie !!!" />
</bean> <!-- 代理对象 -->
<bean id="wsProxy" class="org.springframework.aop.framework.ProxyFactoryBean">
<!-- 代理接口集 -->
<property name="proxyInterfaces">
<list>
<value>cn.org.yinzhengjie.spring.aop.advice.WelcomeService</value>
<value>cn.org.yinzhengjie.spring.aop.advice.WelcomeService2</value>
</list>
</property>
<!-- 拦截器名集合 -->
<property name="interceptorNames">
<list>
<value>beforeAdvice</value>
</list>
</property> <!-- 注意,目标类的名字为"target"关键字,而ref是真正需要被代理的对象连接。一个代理对象一次性只能代理一个类,如果想要代理多个类,需要重新单独定义bean标签哟! -->
<property name="target" ref="wsTarget" /> </bean>
</beans>

5>.编写单元测试类代码

 /*
@author :yinzhengjie
Blog:http://www.cnblogs.com/yinzhengjie/tag/Java%E5%9F%BA%E7%A1%80/
EMAIL:y1053419035@qq.com
*/
package cn.org.yinzhengjie.spring.aop.advice; import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext; public class TestAop {
@Test
public void testAOP1(){
ApplicationContext ac = new ClassPathXmlApplicationContext("aop.xml") ;
WelcomeService ws = (WelcomeService) ac.getBean("wsProxy");
ws.sayHello(); WelcomeService2 ws2 = (WelcomeService2)ws;
ws2.sayHello2(); }
}

  以上代码测试结果如下:

二.AOP的四个通知编程案例

  上面我们已经介绍了Spring的AOP编程中的一个前置通知,其实除了前置通知还有后置通知,循环通知以及异常通知。其实配置文件的方法和上面类似,只不过他们有各自的优点,下面我简单的做个介绍:

    前置通知:主要负责处理调用目标对象之前执行的代码;

    后置通知:主要负责处理调用目标对象之后的执行代码;

    环绕通知:它执行的优先级是在后置通知之前,在前置通知之后的执行的代码,它可以把方法包起来处理,比如在调用方法之前执行一段代码,在调用方法之后,还可以执行一段代码,另外,相比前置通知和通知通知,它还新增了一个返回值的功能;

    异常通知:它执行的优先级暂时没法确定,而且不一定执行,顾名思义,它是在有异常的时候才会触发的代码!因此即使你写了这样的通知,有可能你看不到它的执行结果,除非你故意写一段可能出现异常的代码;

1>.编写测试代码

 /*
@author :yinzhengjie
Blog:http://www.cnblogs.com/yinzhengjie/tag/Java%E5%9F%BA%E7%A1%80/
EMAIL:y1053419035@qq.com
*/
package cn.org.yinzhengjie.spring.aop.advice; public interface WelcomeService {
public abstract void sayHello();
}

WelcomeService.java 文件内容

 /*
@author :yinzhengjie
Blog:http://www.cnblogs.com/yinzhengjie/tag/Java%E5%9F%BA%E7%A1%80/
EMAIL:y1053419035@qq.com
*/
package cn.org.yinzhengjie.spring.aop.advice; public interface WelcomeService2 {
public abstract void sayHello2();
}

WelcomeService2.java 文件内容

 /*
@author :yinzhengjie
Blog:http://www.cnblogs.com/yinzhengjie/tag/Java%E5%9F%BA%E7%A1%80/
EMAIL:y1053419035@qq.com
*/
package cn.org.yinzhengjie.spring.aop.advice; public class WelcomeServiceImpl implements WelcomeService,WelcomeService2{
private String name ; public String getName() {
return name;
} public void setName(String name) {
this.name = name;
} public void sayHello() {
System.out.println(name);
} public void sayHello2() {
System.out.println("Hello Wold");
}
}

WelcomeServiceImpl.java 文件内容

2>.编写通知类

 /*
@author :yinzhengjie
Blog:http://www.cnblogs.com/yinzhengjie/tag/Java%E5%9F%BA%E7%A1%80/
EMAIL:y1053419035@qq.com
*/
package cn.org.yinzhengjie.spring.aop.advice; import org.springframework.aop.MethodBeforeAdvice; import java.lang.reflect.Method; /**
* 前置通知
*/
public class MyMethodBeforeAdvice implements MethodBeforeAdvice {
public void before(Method method, Object[] args, Object target) throws Throwable {
String mname = method.getName() ;
System.out.printf("当前处理的对象 : %s\n调用对象的方法 : %s\n调用参数 : %s\n" , target.toString(),mname.toString(),args.toString());
System.out.println("============= MyMethodBeforeAdvice代码执行完毕 =============");
}
}

MyMethodBeforeAdvice.java 文件内容

 /*
@author :yinzhengjie
Blog:http://www.cnblogs.com/yinzhengjie/tag/Java%E5%9F%BA%E7%A1%80/
EMAIL:y1053419035@qq.com
*/
package cn.org.yinzhengjie.spring.aop.advice; import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation; /**
* 环绕通知,可以篡改行为
*/
public class MyMethodInterceptor implements MethodInterceptor { public Object invoke(MethodInvocation invocation) throws Throwable {
System.out.println("begin");
//调用目标对象方法的返回值
Object tis = invocation.getThis();
System.out.println(tis);
Object ret = invocation.proceed() ;
System.out.println("end");
return ret;
}
}

MyMethodInterceptor.java 文件内容

 /*
@author :yinzhengjie
Blog:http://www.cnblogs.com/yinzhengjie/tag/Java%E5%9F%BA%E7%A1%80/
EMAIL:y1053419035@qq.com
*/
package cn.org.yinzhengjie.spring.aop.advice; import org.springframework.aop.AfterReturningAdvice; import java.lang.reflect.Method; public class MyAfterReturningAdvice implements AfterReturningAdvice {
public void afterReturning(Object returnValue, Method method, Object[] args, Object target) throws Throwable {
System.out.println("over");
}
}

MyAfterReturningAdvice.java 文件内容

 /*
@author :yinzhengjie
Blog:http://www.cnblogs.com/yinzhengjie/tag/Java%E5%9F%BA%E7%A1%80/
EMAIL:y1053419035@qq.com
*/
package cn.org.yinzhengjie.spring.aop.advice; import org.springframework.aop.ThrowsAdvice; import java.lang.reflect.Method; /**
* 异常通知
*/
public class MyThrowableAdvice implements ThrowsAdvice {
public void afterThrowing(Method method, Object[] args, Object target, Exception ex){
System.out.println("出事了!!" + ex.toString());
}
}

MyThrowableAdvice.java 文件内容

3>.编写Spring的配置文件

 <?xml version="1.0"?>
<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:context="http://www.springframework.org/schema/context"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.3.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-4.3.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-4.3.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-4.3.xsd">
<!-- 通知 -->
<bean id="beforeAdvice" class="cn.org.yinzhengjie.spring.aop.advice.MyMethodBeforeAdvice" />
<bean id="afterAdvice" class="cn.org.yinzhengjie.spring.aop.advice.MyAfterReturningAdvice" />
<bean id="aroundAdvice" class="cn.org.yinzhengjie.spring.aop.advice.MyMethodInterceptor" />
<bean id="throwableAdvice" class="cn.org.yinzhengjie.spring.aop.advice.MyThrowableAdvice" /> <!-- 目标对象 -->
<bean id="wsTarget" class="cn.org.yinzhengjie.spring.aop.advice.WelcomeServiceImpl">
<property name="name" value="tom" />
</bean> <!-- 代理对象 -->
<bean id="wsProxy" class="org.springframework.aop.framework.ProxyFactoryBean">
<!-- 代理接口集 -->
<property name="proxyInterfaces">
<list>
<value>cn.org.yinzhengjie.spring.aop.advice.WelcomeService</value>
<value>cn.org.yinzhengjie.spring.aop.advice.WelcomeService2</value>
</list>
</property>
<!-- 拦截器名集合 -->
<property name="interceptorNames">
<list>
<value>beforeAdvice</value>
<value>afterAdvice</value>
<value>aroundAdvice</value>
<value>throwableAdvice</value>
</list>
</property>
<property name="target" ref="wsTarget" />
</bean>
</beans>

4>.编写测试代码

 /*
@author :yinzhengjie
Blog:http://www.cnblogs.com/yinzhengjie/tag/Java%E5%9F%BA%E7%A1%80/
EMAIL:y1053419035@qq.com
*/
package cn.org.yinzhengjie.spring.aop.advice; import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext; public class TestAop {
@Test
public void testAOP1(){
ApplicationContext ac = new ClassPathXmlApplicationContext("aop.xml") ;
WelcomeService ws = (WelcomeService) ac.getBean("wsProxy");
ws.sayHello(); WelcomeService2 ws2 = (WelcomeService2)ws;
ws2.sayHello2(); }
}

5>.运行以上代码执行结果如下:

Java基础-SSM之Spring的AOP编程的更多相关文章

  1. Java基础-SSM之Spring的POJO(Plain Old Java Object)实现AOP

    Java基础-SSM之Spring的POJO(Plain Old Java Object)实现AOP 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 上次我分享过Spring传统的A ...

  2. Java基础-SSM之Spring和Mybatis以及Spring MVC整合案例

    Java基础-SSM之Spring和Mybatis以及Spring MVC整合案例 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 能看到这篇文章的小伙伴,详细你已经有一定的Java ...

  3. Java基础-SSM之Spring和Mybatis整合案例

    Java基础-SSM之Spring和Mybatis整合案例 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任.   在之前我分享过mybatis和Spring的配置案例,想必大家对它们的 ...

  4. Java基础-SSM之Spring MVC入门篇

    Java基础-SSM之Spring MVC入门篇 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.Spring MVC简介 1>.什么是Spring MVC 答:Sprin ...

  5. Java基础-SSM之Spring快速入门篇

    Java基础-SSM之Spring快速入门篇 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任.    Spring是一个开源框架,Spring是于2003 年兴起的一个轻量级的Java ...

  6. Java进阶知识21 Spring的AOP编程

    1.概述 Aop:(Aspect Oriented Programming)面向切面编程          功能: 让关注点代码与业务代码分离! 关注点:重复代码就叫做关注点:切面: 关注点形成的类, ...

  7. Java基础-SSM之mybatis快速入门篇

    Java基础-SSM之mybatis快速入门篇 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 其实你可能会问什么是SSM,简单的说就是spring mvc + Spring + m ...

  8. Java基础复习笔记系列 九 网络编程

    Java基础复习笔记系列之 网络编程 学习资料参考: 1.http://www.icoolxue.com/ 2. 1.网络编程的基础概念. TCP/IP协议:Socket编程:IP地址. 中国和美国之 ...

  9. Java基础复习笔记系列 八 多线程编程

    Java基础复习笔记系列之 多线程编程 参考地址: http://blog.csdn.net/xuweilinjijis/article/details/8878649 今天的故事,让我们从上面这个图 ...

随机推荐

  1. 利用Python统计微信联系人男女比例以及简单的地区分布

    寒暄的话不多说,直接进入主题. 运行效果图: [准备环境] Python版本:v3.5及其以上 开发工具:随意,此处使用Pycharm [依赖包] 1.itchat (CMD运行:pip instal ...

  2. 【第九课】MriaDB密码重置和慢查询日志

    目录 1.如何进行修改MariaDB的密码 2.Mariadb的慢查询日志 1.如何进行修改MariaDB的密码 记得root密码的修改方式: [root@localhost ~]# mysqladm ...

  3. 【第八课】php-fpm.conf配置文件解析

    在discuz论坛的nginx配置文件当中,我们可以看到有一段php解析的配置,如下: location ~ \.php$ { try_files $uri = 404; fastcgi_pass 1 ...

  4. C#_父窗体跟子窗体的控件操作

    很多人都苦恼于如何在子窗体中操作主窗体上的控件,或者在主窗体中操作子窗体上的控件.相比较而言,后面稍微简单一些,只要在主窗体中创建子窗体的时候,保留所创建子窗体对象即可. 下面重点介绍前一种,目前常见 ...

  5. 华为测试大牛Python+Django接口自动化怎么写的?

    有人喜欢创造世界,他们做了开发者:有的人喜欢开发者,他们做了测试员.什么是软件测试?软件测试就是一场本该在用户面前发生的灾难提前在自己面前发生了,这会让他们生出一种救世主的感觉,拯救了用户,也就拯救者 ...

  6. Muduo学习笔记(一) 什么都不做的EventLoop

    Muduo学习笔记(一) 什么都不做的EventLoop EventLoop EventLoop的基本接口包括构造.析构.loop(). One Loop Per Thread 一个线程只有一个Eve ...

  7. C++ 派生类成员的访问属性

    派生类成员的访问属性: C++继承方式总共分为以下几种:public.private.protected三种(它们直接影响到派生类的成员.及其对象对基类成员访问的规则).(1)public(公有继承) ...

  8. 【Beta阶段】第三次Scrum Meeting!

    每日任务内容: 本次会议为第三次Scrum Meeting会议~ 由于本次会议项目经理召开时间依旧较晚(晚上12点半),所以在公寓7层召开,女生参与了线上会议,召开时间大家集会10分钟. 队员 昨日完 ...

  9. Python网络数据采集二

    一.正则表达式 *     表匹配0次或者多次  a*b* +    表至少一次 [ ]   匹配任意一个 ( )  辨识一个编组 {m,n} m或者n 次 [^]  匹配任意不在中括号里的字符 | ...

  10. Python3的bytes和str之别

    Python3不会以任意隐式的方式混用str和bytes,正是这使得:两者的区分特别清晰,在使用Python时不能拼接字符串和字节包,也无法搜索字节包里面的字符串(反之亦然),也不能讲字符串传入参数为 ...