Spring AOP 的简单例子

Spring AOP 的简单例子

       Spring AOP 实现了AOP联盟(Alliance)的制定的接口规范,它基于java的代理机制实现。AOP作为Spring的核心技术之一. 更多关于Spring AOP介绍 可参考:http://oss.org.cn/ossdocs/framework/spring/zh-cn/aop.html  下面给出一个例子来简单介绍Spring AOP具体实现过程

    现假设用户通过login.jsp页面输入相应的用户名和密码之后,首先Spring AOP的环绕通知验证该用户名和密码是否符合要求,若符合要求,则到数据库中查找该用户,若用户存在,将该用户相关的信息写入日志。

1.BaseLoginAdvice 类实现了 前置通知接口(MethodBeforeAdvice)、环绕通知接口(MethodInterceptor)、后置通知接口(AfterReturningAdvice) 这三个接口

BaseLoginAdvice.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
package  com.laoyangx.Aop.chapter0;
 
import  java.lang.reflect.Method;
 
import  org.aopalliance.intercept.MethodInterceptor;
import  org.aopalliance.intercept.MethodInvocation;
import  org.springframework.aop.AfterReturningAdvice;
import  org.springframework.aop.MethodBeforeAdvice;
 
public  abstract  class  BaseLoginAdvice implements  MethodBeforeAdvice, MethodInterceptor,
         AfterReturningAdvice {
     /**
      * @param returnValue 目标方法返回值
      * @param method 目标方法
      * @param args 方法参数
      * @param target 目标对象
      *
      */
     @Override
     public  void  afterReturning(Object returnValue, Method method,
             Object[] args, Object target) throws  Throwable {
         
          throw  new  UnsupportedOperationException( "abstract class CBaseLoginAdvice not implement this method" );
     }
     
     
     /**
      * @param invocation 目标对象的方法
      */
     @Override
     public  Object invoke(MethodInvocation invocation) throws  Throwable {
         
         throw  new  UnsupportedOperationException( "abstract class CBaseLoginAdvice not implement this method" );
     }
 
     /**
      * @param method 将要执行的目标对象方法
      * @param args 方法的参数
      * @param target 目标对象
      */
     @Override
     public  void  before(Method method, Object[] args, Object target)
             throws  Throwable {
         
         throw  new  UnsupportedOperationException( "abstract class CBaseLoginAdvice not implement this method" );
     }
 
}

2.LoginAdviceSupport 类继承 BaseLoginAdvice 类,并重写 BaseLoginAdvice 类的三个方法

LoginAdviceSupport.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
package  com.laoyangx.Aop.chapter0;
 
import  java.lang.reflect.Method;
 
import  org.aopalliance.intercept.MethodInvocation;
 
public  class  LoginAdviceSupport extends  BaseLoginAdvice {
 
     /**
      * 若在数据库中存在指定的用户,将用户登录信息写入日志文件
      * @param returnValue 目标方法返回值
      * @param method 目标方法
      * @param args 方法参数
      * @param target 目标对象
      */
     @Override
     public  void  afterReturning(Object returnValue, Method method,
             Object[] args, Object target) throws  Throwable {
         
        System.out.println( "---------- 程序正在执行 类名: com.laoyangx.Aop.chapter0.LoginAdviceSupport 方法名:afterReturning ----------------" );
       
        //将用户登录信息写入日志文件
     }
    
     /**
      * 验证用户输入是否符合要求
      * @param invocation 目标对象的方法
      */
     @Override
     public  Object invoke(MethodInvocation invocation) throws  Throwable {
         
         System.out.println( "---------- 程序正在执行 类名: com.laoyangx.Aop.chapter0.LoginAdviceSupport 方法名:invoke ----------------" );
         
         String username=invocation.getArguments()[ 0 ].toString();
         String password=invocation.getArguments()[ 1 ].toString();
         
         //在这里进行相关的验证操作 
         
         //假设验证通过
         return  invocation.proceed();
     }
 
     /**
      * 在数据库中查找指定的用户是否存在
      * @param method 将要执行的目标对象方法
      * @param args 方法的参数
      * @param target 目标对象
      */
     @Override
     public  void  before(Method method, Object[] args, Object target)
             throws  Throwable {
         
         System.out.println( "---------- 程序正在执行 类名: com.laoyangx.Aop.chapter0.LoginAdviceSupport 方法名:before ----------------" );
     
          String username=(String)args[ 0 ];
          String passowrd=(String)args[ 1 ];
          
         //在这里进行数据库查找操作
     }
}

3. IUser.java

1
2
3
4
5
6
7
8
9
10
package  com.laoyangx.Aop.chapter0;
 
public  interface  IUser {
     /**
      * 用户登录
      * @param username 用户名
      * @param password 密码
      */
   public  void  Login(String username,String password);
}

4.UserImpl.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
package  com.laoyangx.Aop.chapter0;
 
public  class  UserImpl implements  IUser {
 
     /**
      * 用户登录
      * @param username 用户名
      * @param password 密码
      */
     @Override
     public  void  Login(String username, String password) {
         System.out.println( "---------- 程序正在执行  类名: com.laoyangx.Aop.chapter0.UserImpl 方法名:Login ----------------" );
     }
 
}

5. Spring 的配置文件 login.bean.xml

复制代码
<?xml version="1.0" encoding="UTF-8"?>
<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:tx
="http://www.springframework.org/schema/tx"
xsi:schemaLocation
="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-2.0.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-2.0.xsd"
>

<bean id="loginAdvice" class="com.laoyangx.Aop.chapter0.LoginAdviceSupport"></bean>
<bean id="userTarget" class="com.laoyangx.Aop.chapter0.UserImpl"></bean>

<bean id="user" class="org.springframework.aop.framework.ProxyFactoryBean">
<property name="proxyInterfaces">
<value>com.laoyangx.Aop.chapter0.IUser</value>
</property>
<property name="interceptorNames">
<list>
<value>loginAdvice</value>
</list>
</property>
<property name="target">
<ref bean="userTarget"/>
</property>
</bean>


</beans>
复制代码

6.主程序文件 ConsoleApp.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
package  com.laoyangx.Aop.chapter0;
 
import  org.springframework.context.ApplicationContext;
import  org.springframework.context.support.ClassPathXmlApplicationContext;
 
public  class  ConsoleApp {
 
 
     public  static  void  main(String[] args) {
         
         ApplicationContext ctx=
             new  ClassPathXmlApplicationContext( "com/laoyangx/Aop/chapter0/login.bean.xml" );
         
         IUser user=(IUser)ctx.getBean( "user" );
         user.Login( "username" , "123456" );
 
     }
 
}

运行程序之后,控制台上输出的结果

通过结果可以看到每个函数的执行顺序。关于 前置通知、环绕通知、后置通知 这些术语 网上都有相关的介绍

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值