之所以介绍Jboss AOP,是因为我们的项目要用,项目采用的是ejb,需要使用AOP插入一层,来记录系统日志,后期可能还要插入一层缓存,和安全控制方面的东西。
项目驱动学习嘛,因为我们的应用服务器选择的是jboss,自然要使用jboss自己比较成熟的框架,JBoss AOP
Jboss AOP是一个以Aspected为核心的框架,可用在任何编程环境或与我们的应用服务器紧密集成。面向切面编程(AOP)能让我们更轻松地模块化代码库,很多时候能轻松解决面向对象(OO)不容易解决的问题。Jboss AOP使用JDK 1.5注解,而不是使用单独地注释代码生成java代码。
语言总是乏力,让demo来陈述事实吧。
列举主要类,其他代码
点击这里下载。
- @Stateless
- public class UserManageImpl implements UserManage {
- @AroundInvoke //类内部拦截器1
- public Object myInterceptor1(InvocationContext ic) throws Exception
- {
- System.out.println("myInterceptor-----------1-------------:" + ic.getMethod().getName());
- return ic.proceed();
- }
- @AroundInvoke //类内部拦截器2
- public Object myInterceptor2(InvocationContext ic) throws Exception
- {
- System.out.println("myInterceptor-----------2-------------:" + ic.getMethod().getName());
- return ic.proceed();
- }
- @Override
- public String sayHello(String userName) {
- // TODO Auto-generated method stub
- return "hello!@"+userName;
- }
- @Override
- public String greet(User user) {
- // TODO Auto-generated method stub
- return "greet!@"+user.getName();
- }
- @Override
- public User getUser() {
- // TODO Auto-generated method stub
- User user=new User();
- user.setName("贾琳");
- return user;
- }
- }
Stateless Session Bean中定义了两个拦截器方法和三个普通的bean方法,分别是myInterceptor1和myInterceptor2。当客户端调用sayHello,greet,getUser方法时,EJB容器会先调用myInterceptor1,然后会调用myInterceptor2方法,最后会调用Bean方法。使用拦截器方法时要注意如下几点:
1. 拦截器方法必须有一个返回值,返回值类型是Object。
2. 拦截器方法只能有一个参数,而且该参数类型必须是javax.interceptor.InvocationContext。
3. 只有调用InvocationContext接口的proceed方法,EJB容器才会调用下一个拦截器方法或被拦截的Bean方法。
类内部的拦截器,不推荐使用,插拔不方便,而且放到业务逻辑类中,总感觉那么不伦不类。
下面介绍的是外部的拦截器类,可以拦截不同Bean中的方法,
这点把aop思想发挥到了极致。
。
在这种情况下,需要将拦截器方法放在一个单独的类中。这个类就叫拦截器类。下面是一个拦截器类的代码:
- //拦截器1
- public class UserInterceptor1 {
- @AroundInvoke
- public Object interceptorMethod(InvocationContext ic) throws Exception {
- System.out.println("UserInterceptor-----------1-------------:" + ic.getMethod().getName());
- return ic.proceed();
- }
- }
- //拦截器2
- public class UserInterceptor2 {
- @AroundInvoke
- public Object interceptorMethod(InvocationContext ic) throws Exception {
- System.out.println("UserInterceptor-----------2-------------:" + ic.getMethod().getName());
- return ic.proceed();
- }
- }
- @Stateless
- @Interceptors({UserInterceptor1.class, UserInterceptor2.class}) //多个外部拦截器类
- //@Interceptors(UserInterceptor1.class) // 一个外部拦截器
- public class UserManageImpl implements UserManage {
- @AroundInvoke //类内部拦截器1
- public Object myInterceptor1(InvocationContext ic) throws Exception
- {
- System.out.println("myInterceptor-----------1-------------:" + ic.getMethod().getName());
- return ic.proceed();
- }
- @AroundInvoke //类内部拦截器2
- public Object myInterceptor2(InvocationContext ic) throws Exception
- {
- System.out.println("myInterceptor-----------2-------------:" + ic.getMethod().getName());
- return ic.proceed();
- }
- @ExcludeClassInterceptors //阻止拦截器类中的拦截器方法对Bean方法的拦截
- @Override
- public String sayHello(String userName) {
- // TODO Auto-generated method stub
- return "hello!@"+userName;
- }
- @Override
- public String greet(User user) {
- // TODO Auto-generated method stub
- return "greet!@"+user.getName();
- }
- @Override
- public User getUser() {
- // TODO Auto-generated method stub
- User user=new User();
- user.setName("贾琳");
- return user;
- }
- }
从上面的类中,可以看到:
@Interceptors({UserInterceptor1.class, UserInterceptor2.class}) //多个外部拦截器类,
这个注解完成了拦截器的插入。
@ExcludeClassInterceptors //不需要拦截的方法,即该注解阻止拦截器类中的拦截器方法对Bean方法的拦截
如果指定了多个拦截器类和拦截器方法,就涉及到一个调用顺序的问题。EJB容器会先调用拦截器类中的拦截器方法、如果有多个拦截器类被指定,按指定的顺序进行调用。按UserManageImpl 的注解,UserInterceptor1 类中的拦截器方法,接着是UserInterceptor2。最后会调用在Bean中定义的拦截器方法myInterceptor1和myInterceptor2。
代码很简单,加几个注解就OK。其他代码
点击这里下载。
如果需要更详细的内容,去jboss官网吧,
http://www.jboss.org/jbossaop/
不得不赞叹,能写AOP框架的人很牛,能提炼出AOP思想的人更牛。
从代码中,可以清晰的看到,AOP使应用程序逻辑和系统架构代码更清洁地分离,而且插拔非常方便。我们可以很轻松地插入
缓存,异步通信,事务,安全等许多许多功能模块。
这也给我们合作开发提供了很大便利,开发人员可以分为两种,一种专门负责应用程序业务逻辑的开发,而另一种专门负责系统环境的开发,如日志,权限,缓存等等。