Java基础-SSM之Spring的POJO(Plain Old Java Object)实现AOP
作者:尹正杰
版权声明:原创作品,谢绝转载!否则将追究法律责任。
上次我分享过Spring传统的AOP编程(https://www.cnblogs.com/yinzhengjie/p/9288904.html),也知道AOP编程的其实就是动态代理模式。而本篇博客介绍的是另外一种实现AOP编程的方式,即:直接通过XML和POJO的方式实现AOP编程。
一.xml-pojo实现AOP
1>.配置Maven依赖
1 <?xml version="1.0" encoding="UTF-8"?> 2 <project xmlns="http://maven.apache.org/POM/4.0.0" 3 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 4 xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 5 <modelVersion>4.0.0</modelVersion> 6 7 <groupId>cn.org.yinzhengjie</groupId> 8 <artifactId>MySpring</artifactId> 9 <version>1.0-SNAPSHOT</version> 10 11 <dependencies> 12 <dependency> 13 <groupId>junit</groupId> 14 <artifactId>junit</artifactId> 15 <version>4.11</version> 16 </dependency> 17 <dependency> 18 <groupId>org.springframework</groupId> 19 <artifactId>spring-context-support</artifactId> 20 <version>4.3.5.RELEASE</version> 21 </dependency> 22 <dependency> 23 <groupId>aopalliance</groupId> 24 <artifactId>aopalliance</artifactId> 25 <version>1.0</version> 26 </dependency> 27 <dependency> 28 <groupId>org.aspectj</groupId> 29 <artifactId>aspectjrt</artifactId> 30 <version>1.6.1</version> 31 </dependency> 32 <dependency> 33 <groupId>org.aspectj</groupId> 34 <artifactId>aspectjweaver</artifactId> 35 <version>1.8.10</version> 36 </dependency> 37 </dependencies> 38 </project>
2>.编写Spring的XML配置文件(aop.xml)
1 <?xml version="1.0"?> 2 <beans xmlns="http://www.springframework.org/schema/beans" 3 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 4 xmlns:aop="http://www.springframework.org/schema/aop" 5 xmlns:context="http://www.springframework.org/schema/context" 6 xmlns:tx="http://www.springframework.org/schema/tx" 7 xsi:schemaLocation="http://www.springframework.org/schema/beans 8 http://www.springframework.org/schema/beans/spring-beans-4.3.xsd 9 http://www.springframework.org/schema/aop 10 http://www.springframework.org/schema/aop/spring-aop-4.3.xsd 11 http://www.springframework.org/schema/context 12 http://www.springframework.org/schema/context/spring-context-4.3.xsd 13 http://www.springframework.org/schema/tx 14 http://www.springframework.org/schema/tx "> 15 <!-- 目标对象 --> 16 <bean id="singer" class="cn.org.yinzhengjie.spring.aop.Singer"/> 17 18 <!-- 观众 --> 19 <bean id="audience" class="cn.org.yinzhengjie.spring.aop.Audience"/> 20 21 <aop:config> 22 <aop:aspect id="audienceAspect" ref="audience"> 23 <!-- 24 pointcut : 表示的是切入点; 25 id : 给切入点定义一个标签,这个id的值为audiencePointcut,别人可以通过pointcut-ref属性来引用当前的pointcut切入点; 26 expression : 表示定义表达式; 27 * : 匹配返回值,表示通配符,即返回值类型不限制 28 cn.org.yinzhengjie.spring.aop.Actor.show(..) : 表示执行的方法,需要写完整类名,其中“..”表示参数不限制。 29 --> 30 <aop:pointcut id="audiencePointcut" expression="execution(* cn.org.yinzhengjie.spring.aop.Actor.show(..))"/> 31 <!-- 32 before : 前置通知,表示的是在执行方法之前需要执行的代码。 33 pointcut-ref : 指定切入点链接; 34 method : 表示触发切入点的方法,即切入点在哪个方法中触发; 35 --> 36 <aop:before pointcut-ref="audiencePointcut" method="sitDown"/> 37 <aop:before pointcut-ref="audiencePointcut" method="turnOffCellPhone"/> 38 <!-- 39 after-returning : 后置通知:主要负责处理调用目标对象之后的执行代码; 40 pointcut-ref : 指定切入点链接; 41 method : 表示触发切入点的方法,即切入点在哪个方法中触发; 42 --> 43 <aop:after-returning pointcut-ref="audiencePointcut" method="clap"/> 44 <!-- 45 after-throwing : 异常通知。它执行的优先级暂时没法确定,而且不一定执行,顾名思义,它是在有异常的时候才会触发的代码!因此即 46 使你写了这样的通知,有可能你看不到它的执行结果,除非你故意写一段可能出现异常的代码; 47 --> 48 <aop:after-throwing pointcut-ref="audiencePointcut" method="payOff"/> 49 <!-- 50 after : 最终通知,相当于java异常处理的fanaly代码块,无论如何都会执行的操作; 51 --> 52 <aop:after pointcut-ref="audiencePointcut" method="goHome"/> 53 </aop:aspect> 54 </aop:config> 55 </beans>
3>.编写测试代码
1 /* 2 @author :yinzhengjie 3 Blog:http://www.cnblogs.com/yinzhengjie/tag/Java%E5%9F%BA%E7%A1%80/ 4 EMAIL:y1053419035@qq.com 5 */ 6 package cn.org.yinzhengjie.spring.aop; 7 8 /** 9 * 演员接口 10 */ 11 public interface Actor { 12 public void show(); 13 }
1 /* 2 @author :yinzhengjie 3 Blog:http://www.cnblogs.com/yinzhengjie/tag/Java%E5%9F%BA%E7%A1%80/ 4 EMAIL:y1053419035@qq.com 5 */ 6 package cn.org.yinzhengjie.spring.aop; 7 8 /** 9 * 歌手,目标类 10 */ 11 public class Singer implements Actor { 12 public void show() { 13 System.out.println("I'm yinzhengjie!"); 14 // String ss = null; 15 // ss.toLowerCase() ; 16 } 17 }
1 /* 2 @author :yinzhengjie 3 Blog:http://www.cnblogs.com/yinzhengjie/tag/Java%E5%9F%BA%E7%A1%80/ 4 EMAIL:y1053419035@qq.com 5 */ 6 package cn.org.yinzhengjie.spring.aop; 7 8 /** 9 * 观众类 10 */ 11 public class Audience { 12 13 public void sitDown(){ 14 System.out.println("sitDown"); 15 } 16 public void turnOffCellPhone(){ 17 System.out.println("turnOffCellPhone"); 18 } 19 public void clap(){ 20 System.out.println("clap"); 21 } 22 public void payOff(){ 23 System.out.println("payOff"); 24 } 25 public void goHome(){ 26 System.out.println("goHome"); 27 } 28 }
1 /* 2 @author :yinzhengjie 3 Blog:http://www.cnblogs.com/yinzhengjie/tag/Java%E5%9F%BA%E7%A1%80/ 4 EMAIL:y1053419035@qq.com 5 */ 6 package cn.org.yinzhengjie.spring.aop; 7 8 import org.springframework.context.ApplicationContext; 9 import org.springframework.context.support.ClassPathXmlApplicationContext; 10 11 public class App { 12 public static void main(String[] args) { 13 //加载类的路径XMl配置文件,实例化容器。得到ApplicationContext的对象ac,我们将文件放在“resource”目录下。否则会抛异常找不到文件哟! 14 ApplicationContext ac = new ClassPathXmlApplicationContext("aop.xml"); 15 //通过该ac的getBean方法获取到配置文件中的bean标签的指定id为"singer"的对象,由于返回的是Object对象,因此我们需要强转一下。 16 Actor actor = (Actor) ac.getBean("singer"); 17 //调用actor对象的show方法。 18 actor.show(); 19 } 20 }
以上代码执行结果如下:
二.xml-pojo实现AOP(环绕通知)
1>.配置Maven依赖
1 <?xml version="1.0" encoding="UTF-8"?> 2 <project xmlns="http://maven.apache.org/POM/4.0.0" 3 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 4 xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 5 <modelVersion>4.0.0</modelVersion> 6 7 <groupId>cn.org.yinzhengjie</groupId> 8 <artifactId>MySpring</artifactId> 9 <version>1.0-SNAPSHOT</version> 10 11 <dependencies> 12 <dependency> 13 <groupId>junit</groupId> 14 <artifactId>junit</artifactId> 15 <version>4.11</version> 16 </dependency> 17 <dependency> 18 <groupId>org.springframework</groupId> 19 <artifactId>spring-context-support</artifactId> 20 <version>4.3.5.RELEASE</version> 21 </dependency> 22 <dependency> 23 <groupId>aopalliance</groupId> 24 <artifactId>aopalliance</artifactId> 25 <version>1.0</version> 26 </dependency> 27 <dependency> 28 <groupId>org.aspectj</groupId> 29 <artifactId>aspectjrt</artifactId> 30 <version>1.6.1</version> 31 </dependency> 32 <dependency> 33 <groupId>org.aspectj</groupId> 34 <artifactId>aspectjweaver</artifactId> 35 <version>1.8.10</version> 36 </dependency> 37 </dependencies> 38 </project>
2>.编写Spring的XML配置文件(aop2.xml)
1 <?xml version="1.0"?> 2 <beans xmlns="http://www.springframework.org/schema/beans" 3 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 4 xmlns:aop="http://www.springframework.org/schema/aop" 5 xmlns:context="http://www.springframework.org/schema/context" 6 xmlns:tx="http://www.springframework.org/schema/tx" 7 xsi:schemaLocation="http://www.springframework.org/schema/beans 8 http://www.springframework.org/schema/beans/spring-beans-4.3.xsd 9 http://www.springframework.org/schema/aop 10 http://www.springframework.org/schema/aop/spring-aop-4.3.xsd 11 http://www.springframework.org/schema/context 12 http://www.springframework.org/schema/context/spring-context-4.3.xsd 13 http://www.springframework.org/schema/tx 14 http://www.springframework.org/schema/tx/spring-tx-4.3.xsd"> 15 <!-- 目标对象 --> 16 <bean id="singer" class="cn.org.yinzhengjie.spring.aop2.Singer" /> 17 18 <!-- 观众 --> 19 <bean id="audience" class="cn.org.yinzhengjie.spring.aop2.Audience" /> 20 21 <aop:config> 22 <aop:aspect id="audienceAspect" ref="audience"> 23 <!-- 24 * :统配返回值 25 *. :任何包以及子包 26 . :包和类的分割 27 Actor:类或者接口 28 .* : 类或者接口中的任何方法 29 (..) : 参数不限 30 --> 31 <aop:around method="watch" pointcut="execution(* *..Actor.*(..))" /> 32 </aop:aspect> 33 </aop:config> 34 </beans>
3>.编写测试代码
1 /* 2 @author :yinzhengjie 3 Blog:http://www.cnblogs.com/yinzhengjie/tag/Java%E5%9F%BA%E7%A1%80/ 4 EMAIL:y1053419035@qq.com 5 */ 6 package cn.org.yinzhengjie.spring.aop2; 7 8 /** 9 * 演员接口 10 */ 11 public interface Actor { 12 public void show(); 13 }
1 /* 2 @author :yinzhengjie 3 Blog:http://www.cnblogs.com/yinzhengjie/tag/Java%E5%9F%BA%E7%A1%80/ 4 EMAIL:y1053419035@qq.com 5 */ 6 package cn.org.yinzhengjie.spring.aop2; 7 8 /** 9 * 歌手,目标类 10 */ 11 public class Singer implements Actor { 12 public void show() { 13 System.out.println("我有一只小毛驴,从来也不骑......."); 14 //模拟异常 15 // String ss = null; 16 // ss.toLowerCase() ; 17 } 18 }
1 /* 2 @author :yinzhengjie 3 Blog:http://www.cnblogs.com/yinzhengjie/tag/Java%E5%9F%BA%E7%A1%80/ 4 EMAIL:y1053419035@qq.com 5 */ 6 package cn.org.yinzhengjie.spring.aop2; 7 8 import org.aspectj.lang.ProceedingJoinPoint; 9 10 /** 11 * 观众 12 */ 13 public class Audience { 14 15 /** 16 * 观看表演 17 */ 18 public Object watch(ProceedingJoinPoint pjp){ 19 try { 20 System.out.println("sitDown"); 21 System.out.println("turnOffCellPhone"); 22 Object ret = pjp.proceed(); 23 System.out.println("clap"); 24 return ret ; 25 } catch (Throwable e) { 26 System.out.println("payOff"); 27 } 28 finally { 29 System.out.println("goHome"); 30 } 31 return null ; 32 } 33 }
1 /* 2 @author :yinzhengjie 3 Blog:http://www.cnblogs.com/yinzhengjie/tag/Java%E5%9F%BA%E7%A1%80/ 4 EMAIL:y1053419035@qq.com 5 */ 6 package cn.org.yinzhengjie.spring.aop2; 7 8 import org.springframework.context.ApplicationContext; 9 import org.springframework.context.support.ClassPathXmlApplicationContext; 10 11 public class App { 12 public static void main(String[] args) { 13 ApplicationContext ac = new ClassPathXmlApplicationContext("aop2.xml"); 14 Actor actor = (Actor) ac.getBean("singer"); 15 actor.show(); 16 } 17 }
以上代码执行结果如下:
三.注解方式配置spring
注解是为了给类或者方法加上标记,注解是是可以通过编程提取的,它和注释可不一样哟!
1>.导入Maven依赖
1 <?xml version="1.0" encoding="UTF-8"?> 2 <project xmlns="http://maven.apache.org/POM/4.0.0" 3 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 4 xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 5 <modelVersion>4.0.0</modelVersion> 6 7 <groupId>cn.org.yinzhengjie</groupId> 8 <artifactId>MySpring</artifactId> 9 <version>1.0-SNAPSHOT</version> 10 11 <dependencies> 12 <dependency> 13 <groupId>junit</groupId> 14 <artifactId>junit</artifactId> 15 <version>4.11</version> 16 </dependency> 17 <dependency> 18 <groupId>org.springframework</groupId> 19 <artifactId>spring-context-support</artifactId> 20 <version>4.3.5.RELEASE</version> 21 </dependency> 22 <dependency> 23 <groupId>aopalliance</groupId> 24 <artifactId>aopalliance</artifactId> 25 <version>1.0</version> 26 </dependency> 27 <dependency> 28 <groupId>org.aspectj</groupId> 29 <artifactId>aspectjrt</artifactId> 30 <version>1.6.1</version> 31 </dependency> 32 <dependency> 33 <groupId>org.aspectj</groupId> 34 <artifactId>aspectjweaver</artifactId> 35 <version>1.8.10</version> 36 </dependency> 37 </dependencies> 38 </project>
2>.编写Spring的XML配置文件(aop.xml)
1 <?xml version="1.0"?> 2 <beans xmlns="http://www.springframework.org/schema/beans" 3 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 4 xmlns:aop="http://www.springframework.org/schema/aop" 5 xmlns:context="http://www.springframework.org/schema/context" 6 xmlns:tx="http://www.springframework.org/schema/tx" 7 xsi:schemaLocation="http://www.springframework.org/schema/beans 8 http://www.springframework.org/schema/beans/spring-beans-4.3.xsd 9 http://www.springframework.org/schema/aop 10 http://www.springframework.org/schema/aop/spring-aop-4.3.xsd 11 http://www.springframework.org/schema/context 12 http://www.springframework.org/schema/context/spring-context-4.3.xsd 13 http://www.springframework.org/schema/tx 14 http://www.springframework.org/schema/tx/spring-tx-4.3.xsd"> 15 <!-- 配置组件扫描(目的是扫描出加了注解的类或者包) --> 16 <context:component-scan base-package="cn.org.yinzhengjie.spring.service" /> 17 18 </beans>
3>.编写代码
1 /* 2 @author :yinzhengjie 3 Blog:http://www.cnblogs.com/yinzhengjie/tag/Java%E5%9F%BA%E7%A1%80/ 4 EMAIL:y1053419035@qq.com 5 */ 6 package cn.org.yinzhengjie.spring.service; 7 8 public interface ByeService { 9 public void sayBye() ; 10 }
1 /* 2 @author :yinzhengjie 3 Blog:http://www.cnblogs.com/yinzhengjie/tag/Java%E5%9F%BA%E7%A1%80/ 4 EMAIL:y1053419035@qq.com 5 */ 6 package cn.org.yinzhengjie.spring.service; 7 8 public interface WelcomeService { 9 public void sayHello() ; 10 }
1 /* 2 @author :yinzhengjie 3 Blog:http://www.cnblogs.com/yinzhengjie/tag/Java%E5%9F%BA%E7%A1%80/ 4 EMAIL:y1053419035@qq.com 5 */ 6 package cn.org.yinzhengjie.spring.service; 7 8 import org.springframework.stereotype.Service; 9 10 @Service 11 public class ByeServiceImpl implements ByeService{ 12 private String bye ; 13 14 public ByeServiceImpl(){ 15 System.out.println("new ByeServiceImpl()"); 16 } 17 18 public String getBye() { 19 return bye; 20 } 21 22 public void setBye(String bye) { 23 this.bye = bye; 24 } 25 26 public void sayBye() { 27 System.out.println(bye); 28 } 29 }
1 /* 2 @author :yinzhengjie 3 Blog:http://www.cnblogs.com/yinzhengjie/tag/Java%E5%9F%BA%E7%A1%80/ 4 EMAIL:y1053419035@qq.com 5 */ 6 package cn.org.yinzhengjie.spring.service; 7 8 import org.springframework.context.annotation.Scope; 9 import org.springframework.stereotype.Service; 10 11 import javax.annotation.Resource; 12 13 @Service("yinzhengjie") //注解是可以指定名称的,如果不指定会默认为当前类名并且首字母会小写! 14 @Scope("prototype") //指定Spring bean的范围为原型模式("prototype") 15 public class WelcomeServiceImpl implements WelcomeService{ 16 private String name ; 17 18 private ByeService bs ; 19 public WelcomeServiceImpl(){ 20 System.out.println("new WelcomeServiceImpl()"); 21 } 22 public ByeService getBs() { 23 return bs; 24 } 25 26 //注入依赖,使用关键字name指定具体注入注解,当然也可以不在方法中注入,我们也可以在字段中注入哟! 27 @Resource(name="byeServiceImpl") 28 public void setBs(ByeService bs) { 29 System.out.println("正在注入 : byeServiceImpl"); 30 this.bs = bs; 31 } 32 public String getName() { 33 return name; 34 } 35 public void setName(String name) { 36 this.name = name; 37 } 38 public void sayHello() { 39 bs.sayBye(); 40 System.out.println("I'm yinzhengjie !!!"); 41 } 42 }
1 /* 2 @author :yinzhengjie 3 Blog:http://www.cnblogs.com/yinzhengjie/tag/Java%E5%9F%BA%E7%A1%80/ 4 EMAIL:y1053419035@qq.com 5 */ 6 package cn.org.yinzhengjie.spring.service; 7 8 import org.springframework.context.ApplicationContext; 9 import org.springframework.context.support.ClassPathXmlApplicationContext; 10 11 12 public class App { 13 public static void main(String[] args) { 14 ApplicationContext ac = new ClassPathXmlApplicationContext("beans.xml"); 15 WelcomeService ws = (WelcomeService) ac.getBean("yinzhengjie"); 16 ws.sayHello(); 17 ByeService bs = (ByeService) ac.getBean("byeServiceImpl"); 18 System.out.println(bs); 19 20 } 21 }
以上代码执行结果如下: