Spring AOP @Aspect support annotation
2013-10-30 09:08
309 查看
还是这个例子,我们用完全annotation的方法来实现。代码我就不重复了,跟前面XML配置是同一套。
修改配置文件:
修改Aspect类
运行,输出为:
Dinosaur hall is opened.
The People Zoo is opened.
Before method...
Charge Jack $1.00 for ticket.
Jack needs to be charged first.
Dianosaur hall charges Jack $2.00
Jack visited diano hall.
After return...
Current traffic: 1
Income of DINOSAUR: ¥2.00
Dinosaur hall is closed.
The People Zoo is closed.
一模一样。而且更加简单了。世界如此美好~如此清净……
可以看到用annotation来做AOP,实在是简单的不得了。这里唯一没有摆脱XML的,就是Spring的容器的配置文件。当然,Spring这段配置也可以完全用annotation来做,这样就完全不要applicationContext.xml这个文件了。参考如下步骤:
先把Main类改改,让它支持配置
这里@ComponentScan是为了让Spring自动识别
@Configuration是让该类变成配置类
@EnableAspectJAutoProxy是启动AutoProxy
将几个让Spring自己加载的类变成Component,Spring可以自动识别加载
如果不想让Spring来管理,可以在原类里面把@Component去掉,然后在Main类里面加上
这样就可以通过ctx.getBean("dinoHall")
来获得实例。
最终修改调用过程如下:
输出:
Dinosaur hall is opened.
The People Zoo is opened.
Before method...
Charge Jack $1.00 for ticket.
Jack needs to be charged first.
Dianosaur hall charges Jack $2.00
Jack visited diano hall.
After return...
Current traffic: 1
Income of DINOSAUR: ¥2.00
Dinosaur hall is closed.
The People Zoo is closed.
总结
完全的annotation是非常方便的,就像ejb。但是,Spring的annotation做的还不是非常的完善,有些地方还需要提高。例如,在
Hall dinoHall = (Hall)ctx.getBean("dinoHall");
这里,我们如果不定义
@Bean(name="dinoHall")
public Hall getDinoHall()
{
return new DinoHall();
}
在DinoHall上加上@Component后,用
Hall dinoHall = (Hall)ctx.getBean(Hall.class);
来获得实例,这里有个问题就是,后面传参的class,如果该类实现了接口,必须得传入其接口才行,否则就会报异常:
org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [com.edi.poc.DinoHall] is defined
这个我怀疑是因为Spring的容器智能的选择了JDK的动态代理来反射生成实际类,而JDK的动态代理要求Target必须实现接口。理论上改成强制CGLIB应该能解决问题,但是我找了下,并没找到如何用annotation来标示强制使用CGLIB……
还例如,Spring3现在支持JSR-250定义的@PostConsturct等生命周期管理的注解,但是,我也没有找到如何使用annotation来启用。网上和官方文档都是给出了修改配置文件来使其支持。
本文源码:
https://github.com/EdisonXu/POC/tree/master/intro-aop
修改配置文件:
<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"> <!-- Configure Target Objects --> <bean id="zoo" class="com.edi.poc.Zoo"> <constructor-arg value="People"/> </bean> <bean id="dinoHall" class="com.edi.poc.DinoHall"/> <bean id="jack" class="com.edi.poc.Tourer"> <constructor-arg value="Jack"/> </bean> <bean id="myAspect" class="com.edi.poc.aop.MyAspect"/> <aop:aspectj-autoproxy/> </beans> |
@Aspect public class MyAspect { @Before("execution(* com.edi.poc.Zoo.enter(..))") public void before(JoinPoint joinPoint) { System.out.println("Before method..."); Statistic.increaseTotalTraffic(); } @After("execution(* com.edi.poc.ifc.Hall.visit(..))") public void after(JoinPoint joinPoint) { System.out.println("After return..."); Statistic.increaseIncome(HALL_NAME.DINOSAUR, BigDecimal.valueOf(2l)); } } |
Dinosaur hall is opened.
The People Zoo is opened.
Before method...
Charge Jack $1.00 for ticket.
Jack needs to be charged first.
Dianosaur hall charges Jack $2.00
Jack visited diano hall.
After return...
Current traffic: 1
Income of DINOSAUR: ¥2.00
Dinosaur hall is closed.
The People Zoo is closed.
一模一样。而且更加简单了。世界如此美好~如此清净……
可以看到用annotation来做AOP,实在是简单的不得了。这里唯一没有摆脱XML的,就是Spring的容器的配置文件。当然,Spring这段配置也可以完全用annotation来做,这样就完全不要applicationContext.xml这个文件了。参考如下步骤:
先把Main类改改,让它支持配置
@ComponentScan @Configuration @EnableAspectJAutoProxy public class Main { …. } |
@Configuration是让该类变成配置类
@EnableAspectJAutoProxy是启动AutoProxy
将几个让Spring自己加载的类变成Component,Spring可以自动识别加载
@Component public class Zoo { … } @Component public class DinoHall implements Hall { … } @Aspect @Component public class MyAspect { … } |
public class Main { @Bean(name="dinoHall") public Hall getDinoHall() { return new DinoHall(); } } |
来获得实例。
最终修改调用过程如下:
public static void main(String[] args) { ApplicationContext ctx = new AnnotationConfigApplicationContext(Main.class); Zoo zoo = (Zoo) ctx.getBean(Zoo.class); zoo.init("People"); Hall dinoHall = (Hall)ctx.getBean("dinoHall"); zoo.addHall(HALL_NAME.DINOSAUR, dinoHall); Tourer jack = new Tourer("Jack"); zoo.open(); jack.visit(zoo, HALL_NAME.DINOSAUR); System.out.println("Current traffic: " + Statistic.getTotalTraffic()); NumberFormat currency = NumberFormat.getCurrencyInstance(); System.out.println("Income of " + HALL_NAME.DINOSAUR + ": "+ currency.format(Statistic.getIncome(HALL_NAME.DINOSAUR))); zoo.close(); } |
Dinosaur hall is opened.
The People Zoo is opened.
Before method...
Charge Jack $1.00 for ticket.
Jack needs to be charged first.
Dianosaur hall charges Jack $2.00
Jack visited diano hall.
After return...
Current traffic: 1
Income of DINOSAUR: ¥2.00
Dinosaur hall is closed.
The People Zoo is closed.
总结
完全的annotation是非常方便的,就像ejb。但是,Spring的annotation做的还不是非常的完善,有些地方还需要提高。例如,在
Hall dinoHall = (Hall)ctx.getBean("dinoHall");
这里,我们如果不定义
@Bean(name="dinoHall")
public Hall getDinoHall()
{
return new DinoHall();
}
在DinoHall上加上@Component后,用
Hall dinoHall = (Hall)ctx.getBean(Hall.class);
来获得实例,这里有个问题就是,后面传参的class,如果该类实现了接口,必须得传入其接口才行,否则就会报异常:
org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [com.edi.poc.DinoHall] is defined
这个我怀疑是因为Spring的容器智能的选择了JDK的动态代理来反射生成实际类,而JDK的动态代理要求Target必须实现接口。理论上改成强制CGLIB应该能解决问题,但是我找了下,并没找到如何用annotation来标示强制使用CGLIB……
还例如,Spring3现在支持JSR-250定义的@PostConsturct等生命周期管理的注解,但是,我也没有找到如何使用annotation来启用。网上和官方文档都是给出了修改配置文件来使其支持。
本文源码:
https://github.com/EdisonXu/POC/tree/master/intro-aop
相关文章推荐
- Spring_AOP_Annotation使用Aspect实现动态代理
- Spring AOP @Aspect support XML
- Spring_AOP_Annotation使用Aspect实现动态代理 .
- Spring Aop Annotation @Aspect
- spring aop aspect + annotation实现缓存命中判断
- Spring Aspect AOP Annotation
- 05 Spring Aop实例(AOP 如此简单)@Aspect、@Around 注解方式配置
- Spring_demo5_AOP_Annotation
- 【学习】Spring 的 AOP :基于Annotation 的“零配置”方式
- 循序渐进之Spring AOP(6) - 使用@Aspect注解
- 【学习】Spring 的 AOP :基于Annotation 的“零配置”方式
- Spring AOP之通知(advice),连点(connetDoint),切点(pointcut),切点(aspect)
- 基于 Annotation 拦截的 Spring AOP 权限验证方法
- spring aop :logaspect配置
- 基于 Annotation 拦截的 Spring AOP 权限验证方法
- [Java] Spring_1500_AOP_Annotation
- AOP:spring 的Annotation配置
- 05 Spring Aop实例(AOP 如此简单)@Aspect、@Around 注解方式配置
- 使用Spring AOP与Annotation所需的jar包以及命名空间操作
- Spring_007_AOP_Annotation