Spring-AOP
来源:互联网 发布:网络男歌手好听的歌 编辑:程序博客网 时间:2024/05/29 11:31
JavaConfig:
1 package com.spring.config; 2 3 import org.springframework.context.annotation.ComponentScan; 4 import org.springframework.context.annotation.Configuration; 5 import org.springframework.context.annotation.EnableAspectJAutoProxy; 6 7 @Configuration 8 @ComponentScan(basePackages={"com.spring"}) 9 @EnableAspectJAutoProxy10 public class CreatureSpingConfig {11 }
1 package com.spring.aop; 2 3 import org.aspectj.lang.ProceedingJoinPoint; 4 import org.aspectj.lang.annotation.After; 5 import org.aspectj.lang.annotation.Around; 6 import org.aspectj.lang.annotation.Aspect; 7 import org.aspectj.lang.annotation.Before; 8 import org.aspectj.lang.annotation.Pointcut; 9 import org.springframework.stereotype.Component;10 11 @Component12 @Aspect//需要引入aspectjrt-1.*.*.jar,此处版本需要和jdk版本匹配13 public class Sophomore implements Student{14 /**15 * 定义切点,下面的没有方法体的方法只是相当于一个别名16 */17 @Pointcut("execution(* com.spring.aop.ChineseTeacher.teach(..))")18 public void begin(){}19 @Pointcut("execution(* com.spring.aop.ChineseTeacher.classOver(..))")20 public void over(){}21 22 @Before("begin()")23 public void beforeTest(){24 System.out.println("班长:上课!\n童鞋们:老师好!");25 }26 @Around("begin()")27 public void aroundTest(ProceedingJoinPoint p){28 try {29 System.out.println("叮铃铃~");30 p.proceed();//继续执行连接点的方法,如果不写表示不调用这个连接点的方法31 } catch (Throwable e) {32 System.out.println("自习ing");//上课出错则自习33 }34 }35 @Before("over()")36 public void ringTest(){37 System.out.println("叮铃铃~");38 }39 @After("over()")40 public void afterTest(){41 System.out.println("班长:下课!\n童鞋们:老师再见!");42 }43 }
1 package com.spring.aop; 2 3 import org.springframework.stereotype.Component; 4 5 @Component 6 public class ChineseTeacher implements Teacher{ 7 @Override 8 public void teach() { 9 System.out.println("同学们好,今天我们来学习一首诗《锄禾》...");10 }11 public void classOver(){12 System.out.println("今天先讲到这里,同学们下课!");13 }14 }
1 package com.spring.test; 2 3 import org.junit.Test; 4 import org.junit.contrib.java.lang.system.StandardOutputStreamLog; 5 import org.junit.runner.RunWith; 6 import org.springframework.beans.factory.annotation.Autowired; 7 import org.springframework.test.context.ContextConfiguration; 8 import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; 9 10 import com.spring.aop.Teacher;11 @RunWith(SpringJUnit4ClassRunner.class)12 @ContextConfiguration(classes=com.spring.config.CreatureSpingConfig.class)13 public class SpringJunit {14 public static StandardOutputStreamLog log=new StandardOutputStreamLog();15 @Autowired16 private Teacher t;17 @Test18 public void notNull() {19 t.teach();20 System.out.println("45分钟后...");21 t.classOver();22 }23 }
XML:
1 <?xml version="1.0" encoding="UTF-8"?> 2 <beans 3 xmlns="http://www.springframework.org/schema/beans" 4 xmlns:c="http://www.springframework.org/schema/c" 5 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 6 xmlns:p="http://www.springframework.org/schema/p" 7 xmlns:jdbc="http://www.springframework.org/schema/jdbc" 8 xmlns:jee="http://www.springframework.org/schema/jee" 9 xmlns:aop="http://www.springframework.org/schema/aop"10 xmlns:context="http://www.springframework.org/schema/context"11 xmlns:conditional="http://www.springframework.org/schema/context"12 xsi:schemaLocation="http://www.springframework.org/schema/beans 13 http://www.springframework.org/schema/beans/spring-beans.xsd14 http://www.springframework.org/schema/context 15 http://www.springframework.org/schema/context/spring-context.xsd16 http://www.springframework.org/schema/jdbc 17 http://www.springframework.org/schema/jdbc/spring-jdbc.xsd18 http://www.springframework.org/schema/aop19 http://www.springframework.org/schema/aop/spring-aop.xsd20 http://www.springframework.org/schema/jee 21 http://www.springframework.org/schema/jee/spring-jee.xsd22 http://www.springframework.org/schema/conditional 23 http://www.springframework.org/schema/conditional/spring-conditional.xsd">24 <context:annotation-config ></context:annotation-config>25 <bean id="chineseTeacher" class="com.spring.aop.ChineseTeacher"></bean>26 <bean id="sophomore" class="com.spring.aop.Sophomore"></bean>27 <aop:aspectj-autoproxy proxy-target-class="true"/>28 <aop:config>29 <aop:aspect ref="sophomore">30 <aop:pointcut expression="execution(* com.spring.aop.ChineseTeacher.teach(..))" id="begin()"/>31 <aop:pointcut expression="execution(* com.spring.aop.ChineseTeacher.classOver(..))" id="over()"/>32 <aop:around method="aroundTest" pointcut-ref="begin()"/>33 <aop:before method="beforeTest()" pointcut-ref="begin()"/>34 <aop:before method="ringTest()" pointcut-ref="over()"/>35 <aop:after method="afterTest()" pointcut-ref="over()"/>36 </aop:aspect>37 </aop:config>38 </beans>
配置类:
1 package com.spring.config; 2 3 import org.springframework.context.annotation.ComponentScan; 4 import org.springframework.context.annotation.Configuration; 5 import org.springframework.context.annotation.EnableAspectJAutoProxy; 6 7 @Configuration 8 @ComponentScan(basePackages={"com.spring"}) 9 @EnableAspectJAutoProxy10 public class SpringConfig {11 }
学生实现类:
1 package com.spring.aop; 2 3 import org.aspectj.lang.ProceedingJoinPoint; 4 import org.aspectj.lang.annotation.After; 5 import org.aspectj.lang.annotation.Around; 6 import org.aspectj.lang.annotation.Aspect; 7 import org.aspectj.lang.annotation.Before; 8 import org.aspectj.lang.annotation.Pointcut; 9 import org.springframework.stereotype.Component;10 public class Sophomore implements Student{11 public void beforeTest(){12 System.out.println("班长:上课!\n童鞋们:老师好!");13 }14 public void aroundTest(ProceedingJoinPoint p){15 try {16 System.out.println("叮铃铃~");17 p.proceed();//继续执行连接点的方法,如果不写表示不调用这个连接点的方法18 } catch (Throwable e) {19 System.out.println("自习ing");//上课出错则自习20 }21 }22 public void ringTest(){23 System.out.println("叮铃铃~");24 }25 public void afterTest(){26 System.out.println("班长:下课!\n童鞋们:老师再见!");27 }28 }
教师实现类:
1 package com.spring.aop; 2 3 public class ChineseTeacher implements Teacher{ 4 public void teach() { 5 System.out.println("同学们好,今天我们来学习一首诗《锄禾》..."); 6 } 7 public void classOver(){ 8 System.out.println("今天先讲到这里,同学们下课!"); 9 }10 }
测试:
1 package com.spring.aop; 2 3 import org.junit.Test; 4 import org.junit.contrib.java.lang.system.StandardOutputStreamLog; 5 import org.junit.runner.RunWith; 6 import org.springframework.beans.factory.annotation.Autowired; 7 import org.springframework.test.context.ContextConfiguration; 8 import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; 9 10 import com.spring.aop.Teacher;11 @RunWith(SpringJUnit4ClassRunner.class)12 @ContextConfiguration(locations="/spring.xml")13 public class SpringJunit {14 public static StandardOutputStreamLog log=new StandardOutputStreamLog();15 @Autowired16 private Teacher t;17 @Test18 public void notNull() {19 t.teach();20 System.out.println("45分钟后...");21 t.classOver();22 }23 }
结果:
总结:
- @Aspect需要导入aspectjrt.jar;
- 在配置类或xml配置文件中应配置@EnableAspectJAutoProxy或<aop:aspectj-autoproxy/>
- 需要引入aopaliance.jar,否则会报错:java.lang.ClassNotFoundException: org.aopalliance.intercept.MethodInterceptor
- 需要引入aspectjweaver.jar,否则会报错:java.lang.ClassNotFoundException: org.aspectj.weaver.reflect.ReflectionWorld$ReflectionWorldException
- 过程中可能出现如下异常:java.lang.IllegalArgumentException: error at ::0 can't find referenced pointcut teach,原因是:aspectjrt.jar版本与jdk版本不一致,解决办法参考:http://www.cnblogs.com/xing901022/p/4267563.html
- jar包下载地址:http://mavenrepository.com/
- JavaConfig方式中:before方法的优先级比around低
- execution(* com.spring.aop.ChineseTeacher.teach(..))扩展
AOP支持的AspectJ切入点指示符如下:
execution:用于匹配方法执行的连接点;
within:用于匹配指定类型内的方法执行;
this:用于匹配当前AOP代理对象类型的执行方法;注意是AOP代理对象的类型匹配,这样就可能包括引入接口也类型匹配;
target:用于匹配当前目标对象类型的执行方法;注意是目标对象的类型匹配,这样就不包括引入接口也类型匹配;
args:用于匹配当前执行的方法传入的参数为指定类型的执行方法;
@within:用于匹配所以持有指定注解类型内的方法;
@target:用于匹配当前目标对象类型的执行方法,其中目标对象持有指定的注解;
@args:用于匹配当前执行的方法传入的参数持有指定注解的执行;
@annotation:用于匹配当前执行方法持有指定注解的方法;
bean:Spring AOP扩展的,AspectJ没有对于指示符,用于匹配特定名称的Bean对象的执行方法;
reference pointcut:表示引用其他命名切入点,只有@ApectJ风格支持,Schema风格不支持。
AspectJ切入点支持的切入点指示符还有: call、get、set、preinitialization、staticinitialization、initialization、handler、adviceexecution、withincode、cflow、cflowbelow、if、@this、@withincode;但Spring AOP目前不支持这些指示符,使用这些指示符将抛出IllegalArgumentException异常。这些指示符Spring AOP可能会在以后进行扩展。
- XML方式中,执行顺序是自上而下,与JavaConfig方式不同;
- XML方式中,在<aop:around>标签中,method方法不需加(),无参方法可以,如果是around方法,必须有ProceedingJoinPoint类的参数,因此会报错:
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name '(inner bean)#1d03f44': Initialization of bean failed; nested exception is java.lang.IllegalArgumentException: Unable to locate method [aroundTest()] on bean [sophomore]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:547)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:475)
at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveInnerBean(BeanDefinitionValueResolver.java:276)
... 65 more
- AOP、Spring的AOP
- AOP--Spring AOP
- Spring AOP 嵌套AOP
- spring AOP
- Spring AOP
- Spring AOP
- spring aop
- Spring AOP
- spring AOP
- spring aop
- Spring aop
- Spring-AOP
- Spring AOP
- spring aop
- spring aop
- Spring AOP
- Spring AOP
- Spring Aop
- Spring-bean的作用域
- windows环境下mongodb下载、安装和使用总结
- ActiveMQ笔记(1):编译、安装、示例代码
- Spring-注入外部值
- SQL-字符串连接聚合函数
- Spring-AOP
- 使用GitHub和Eclipse进行javaEE开发步骤
- MyEclipse安装EGit插件方法
- server library[unbound] 服务未绑定解决办法
- Shimeji开源桌宠代码学习(1)
- Spring-JDBC配置
- 解决error: Your local changes to the following files would be overwritten by merge
- 计算机概述,键盘快捷键,常见的DOS命令,Java语言概述,JDK、JRE、JVM之间的关系,环境变量的配置
- Tomcat的性能优化及部署时的参数调整