Spring 的AOP运用

     Spirng的Aop是面向方面编程的一种。面向方面编程的原理是将程序中涉及的公共问题集中解决。实现功能的方面代码在Aop中又称为通知。

Spirng的Aop分为前置通知,后置通知,环绕通知还有异常通知。


【第1步】分别实现不同的接口,编写程序中涉及的公共问题集中解决的代码

   ①前置通知:在目标方法前执行的代码
    
    import java.lang.reflect.Method;//★★导包
    import org.springframework.aop.MethodBeforeAdvice;//★★

    public class MyBeforeAdvice implements MethodBeforeAdvice//★★实现MethodBeforeAdvice接口
    {
 
       public void before(Method m, Object[] args, Object target) throws Throwable
       {
                System.out.println("==========前置通知的before方法开始====================");
  System.out.println("下面是方法调用的信息:");
  System.out.println("所执行的方法是:" + m);
  System.out.println("调用方法的参数是:" + args);
  System.out.println("目标对象是:" + target);
  System.out.println("==========前置通知的before方法结束====================");
       }
    }

============================================================

   ②后置通知:在目标方法后执行的代码

    import java.lang.reflect.Method;//★★导包
    import org.springframework.aop.AfterReturningAdvice;//★★

    public class MyAfterAdvice implements AfterReturningAdvice//★★实现AfterReturningAdvice接口
    { 
        public void afterReturning(Object returnValue, Method m, Object[] args, Object target)throws Throwable
 {
             System.out.println("============后置通知的after方法开始================");
  System.out.println("目标方法的返回值是 : " + returnValue);
  System.out.println("目标方法是 : " + m);
  System.out.println("目标方法的参数是 : " + args);
  System.out.println("目标对象是 : " + target);
  System.out.println("============后置通知的after方法结束================");
        }
    }

============================================================
 
   ③环绕通知:在目标方法前后执行的代码(只能在目标方法的前后加代码,但不能修目标方法)

    import org.aopalliance.intercept.MethodInterceptor;//★★导包
    import org.aopalliance.intercept.MethodInvocation;//★★


    public class MyAroundInterceptor implements MethodInterceptor//★★实现MethodInterceptor接口
    {
 
        public Object invoke(MethodInvocation invocation) throws Throwable//★★注意invoke方法,只有一个参数。因为不需要修改目标方法
 {
               System.out.println("=========环绕方法调用开始(编写前置代码)===============");
               Object rval = invocation.proceed();//★★★★调用目标方法,返回值用Object类型去接收
               System.out.println("=========环绕方法调用结束(编写后置代码)===============");
               return rval;
        }
    }

============================================================

   ④异常通知:当系统抛出异常的时候执行的代码

   import org.springframework.aop.ThrowsAdvice;//★★导包
   import java.lang.reflect.Method;//★★
   import java.lang.reflect.Type;//★★

   public class Throw implements ThrowsAdvice//实现ThrowsAdvice接口  
   {  
      public void afterThrowing(Method method,Object[] args,Object target,RuntimeException throwable)//★★ {  

                System.out.println("=========异常通知的afterThrowing方法调用开始===============");  
                System.out.println("方法名: " + method.getName());

                //★★获取参数的类型 
                Type[] type = method.getGenericParameterTypes();  
                for(int i = 0; i < type.length; i++) {  
                      System.out.println(type[i].toString() + ": " + args[i]);  
                }  

                System.out.println("目标类对象: " + target.toString());  
                System.out.println("异常是:" + throwable.getClass().getName()); 
 
                System.out.println("=========异常通知的afterThrowing方法调用结束===============");  

      }  
   } 

 


========================================================================================

 


【第2步】编写目标类(只要实现核心代码)


 public interface  Person
 {
 void info();
 void run();
 }


 public class PersonImpl implements Person
 {
 private String name;
 private int age;

 public void setName(String name)
 {
  this.name = name;
 }
 public void setAge(int age)
 {
  this.age = age;
 }

 public void info()
 {
  System.out.println("我的名字是:  " + name + " , 今年年龄为:  " + age);
 }
 public void run()
 {
  if (age < 45)
  {
   System.out.println("我还年轻,奔跑迅速...");
  }
  else
  {
   System.out.println("我年老体弱,只能慢跑...");
  }
 }
 }

 


========================================================================================

 


【第3步】用Spring配置Bean之间的依赖

== applicationContext.xml ==

       ...   ...   ...

       //********目标类Bean的注入********
       <bean id="personTarget" class="wlg.PersonImpl">
  <property name="name">
   <value>Wawa</value>
  </property>
  <property name="age">
   <value>51</value>
  </property>
 </bean>


 <bean id="myAdvice" class="wlg.MyBeforeAdvice"/>   //********前置通知********
 <bean id="myAroundInterceptor" class="wlg.MyAroundInterceptor"/>   //********环绕通知********
        <bean id="throwAdvisor" class="wlg.Throw"/>   //********异常通知********

        //★★★★********后置通知(通过RegexpMethodPointcutAdvisor类对特定的方法进行配置通知)********
 <bean id="runAdvisor" class="org.springframework.aop.support.RegexpMethodPointcutAdvisor">
  <property name="advice">
   <bean class="wlg.MyAfterAdvice"/>   //★★对应的JavaBean
  </property>
  <property name="patterns">
   <list>
   <value>.*run.*</value>   //★★对应的接口中的方法名,这里指的是对只要是方法名中含有"run"的方法就实行配置好的通知
   <value>wlg.Person.info</value>  //只对wlg.Person接口中的info方法实行配置好的通知
                        </list>
  </property>
 </bean>
 
 //★★★★********对通知与目标类之间进行代理(后台运用的是java中的代理模式)********
 <bean id="person" class="org.springframework.aop.framework.ProxyFactoryBean">//★★对应的类是Spring的ProxyFactoryBean类
  <property name="proxyInterfaces">
   <value>wlg.Person</value>  //★★proxyInterfaces属性对应的是目标类要实现的接口
  </property>
  <property name="target">
   <ref local="personTarget"/>   //★★target对应的是目标类  
  </property>
  <property name="interceptorNames">  //★★interceptorNames对应的是通知类,属性是个集合
   <list>
    <value>runAdvisor</value>
    <value>myAdvice</value>
    <value>myAroundInterceptor</value>
    <value>throwAdvisor</value>
   </list>
  </property>
 </bean>


       ...   ...   ...

 


========================================================================================

 


【第4步】OAP的运用


  import org.springframework.context.ApplicationContext;//导包
  import org.springframework.context.support.FileSystemXmlApplicationContext;


  public class BeanTest
  {
      public static void main(String[] args)throws Exception
      {
  ApplicationContext ctx = new FileSystemXmlApplicationContext("E://applicationContext.xml");//加载Spring的配置文件
  Person p = (Person)ctx.getBean("person");//通过配置好的配置注入Bean对象实例(注意,这里用的是接口作为引用)
  p.info();//调用方法
                System.out.println("===================第一个方法结束========================");
  p.run();
      }
  }

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值