Spring Aop学习

首先AOP是OOP的一种补充

 

Spring实现AOP有两种方式

    1.使用注解

    2.配置XML

 

一、使用注解

 

先搞好需要注入的方法

package com.zhyonk.serviceImpl;

import com.zhyonk.service.PersonService;

public class PersonServiceImpl implements PersonService{

    @Override
    public void save(String name) {
        System.out.println("我是save方法");  
    }

    @Override
    public void update(String name, Integer id) {
        System.out.println("我是update()方法");  
    }

    @Override
    public String getPersonName(Integer id) {
        System.out.println("我是getPersonName()方法");  
        return "xxx";
    }
}

 

接下来搞一个切面类

package com.zhyonk.aspect;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint; 

public class MyAspect {
    
    public void before(JoinPoint point){
            String name = point.getTarget().getClass().getName();
            System.out.println("注入"+name+"方法"+"...前置通知");
    }
    
    public void afterReturn(){
        
        System.out.println("方法结束了。。。后置通知");
        
    }
    
    public void after(){
        System.out.println("不管方法有没有执行完。一定会执行的方法...最终通知");
    }
    
    public void afterThrowing(){
        System.out.println("方法执行时发生异常。。。执行异常通知");
    }
    
    public Object Around(ProceedingJoinPoint point) throws Throwable{
        
        Object obj = null;     
        System.out.println("进入Around通知");
        try {     
            obj = point.proceed();     //在这里获得需要切入的对象,将要切入的对象用ASM框架进行字节码重新编译
            System.out.println("退出Around通知");
        } catch (Throwable e) {     
    
            this.afterThrowing();  //相当于异常抛出后通知     
            throw e;     
        }finally{     
           System.out.println("Around中一定会执行的方法");
        }     
        return obj;         //返回编译之后的字节码生成的对象
    }
}

然后在xml中进行配置

  

    <bean id="personServiceImpl" class="com.zhyonk.serviceImpl.PersonServiceImpl" />
    
    <bean id="myAspectBean" class="com.zhyonk.aspect.MyAspect"/>
    
    <aop:config>
        <aop:aspect id="myAspect" ref="myAspectBean">
            <aop:pointcut expression="execution(* com.zhyonk.serviceImpl.PersonServiceImpl.*(..))" id="anyMethod"/>
            <aop:before method="before" pointcut-ref="anyMethod"/>
            <aop:after method="after" pointcut-ref="anyMethod"/>
            <aop:after-throwing method="afterThrowing" pointcut-ref="anyMethod"/>
            <aop:after-returning method="afterReturn" pointcut-ref="anyMethod"/>
            <aop:around method="Around" pointcut-ref="anyMethod"/>
            
        </aop:aspect>
    </aop:config>

哦了

运行结果

 1 INFO : org.springframework.context.support.FileSystemXmlApplicationContext - Refreshing org.springframework.context.support.FileSystemXmlApplicationContext@536c73aa: startup date [Fri Dec 23 09:24:30 GMT+08:00 2016]; root of context hierarchy
 2 INFO : org.springframework.beans.factory.xml.XmlBeanDefinitionReader - Loading XML bean definitions from file [C:\dev\workspace\Eclipseworkspace\Spring\src\main\webapp\WEB-INF\spring\root-context.xml]
 3 INFO : org.springframework.beans.factory.support.DefaultListableBeanFactory - Pre-instantiating singletons in org.springframework.beans.factory.support.DefaultListableBeanFactory@48d3b591: defining beans [org.springframework.aop.config.internalAutoProxyCreator,personServiceImpl,myAspectBean,org.springframework.aop.aspectj.AspectJPointcutAdvisor#0,org.springframework.aop.aspectj.AspectJPointcutAdvisor#1,org.springframework.aop.aspectj.AspectJPointcutAdvisor#2,org.springframework.aop.aspectj.AspectJPointcutAdvisor#3,org.springframework.aop.aspectj.AspectJPointcutAdvisor#4,anyMethod]; root of factory hierarchy
 4 注入com.zhyonk.serviceImpl.PersonServiceImpl方法...前置通知
 5 进入Around通知
 6 我是save方法
 7 不管方法有没有执行完。一定会执行的方法...最终通知
 8 方法结束了。。。后置通知
 9 退出Around通知
10 Around中一定会执行的方法

 

总结一下,用xml文件配置的话比较繁琐。需要将注入的方法声明在xml<aop:config>中,先搞一个<aop:poincut/>在讲需要的方法befoe、after之类的写进去

再看一下执行结果。

before>around>Method(要注入的方法)>after-return>after

 

在看一下用Annotation进行注入

还是用之前的那个需要注入的类

搞一个注入类,在类中进行声明

package com.zhyonk.interceptor;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;

@Aspect
public class MyInterceptor {

    @Pointcut("execution(* com.zhyonk.serviceImpl.PersonServiceImpl.*(..))")
    private void anyMethod(){}//定义一个切入点  

    @Before("anyMethod() && args(name)")
    public void doAccessCheck(String name) {
        System.out.println(name);
        System.out.println("前置通知");
    }

    @AfterReturning("anyMethod()")
    public void doAfter() {
        System.out.println("后置通知");
    }

    @After("anyMethod()")
    public void after() {
        System.out.println("最终通知");
    }

    @AfterThrowing("anyMethod()")
    public void doAfterThrow() {
        System.out.println("例外通知");
    }

    @Around("anyMethod()")
    public Object doBasicProfiling(ProceedingJoinPoint pjp) throws Throwable {
        System.out.println("进入环绕通知");
        Object object = pjp.proceed();// 执行该方法
        System.out.println("退出方法");
        return object;
    }
}

然后在xml的IOC容器中加入Bean

运行结果

 1 INFO : org.springframework.context.support.FileSystemXmlApplicationContext - Refreshing org.springframework.context.support.FileSystemXmlApplicationContext@751dc8af: startup date [Fri Dec 23 09:40:38 GMT+08:00 2016]; root of context hierarchy
 2 INFO : org.springframework.beans.factory.xml.XmlBeanDefinitionReader - Loading XML bean definitions from file [C:\dev\workspace\Eclipseworkspace\Spring\src\main\webapp\WEB-INF\spring\root-context.xml]
 3 INFO : org.springframework.beans.factory.support.DefaultListableBeanFactory - Pre-instantiating singletons in org.springframework.beans.factory.support.DefaultListableBeanFactory@5fe633e4: defining beans [org.springframework.aop.config.internalAutoProxyCreator,myInterceptor,personServiceImpl,myAspectBean]; root of factory hierarchy
 4 进入环绕通知
 5 ....
 6 前置通知
 7 我是save方法
 8 最终通知
 9 退出方法
10 后置通知

结果和上面一样。。

很简单的感觉。

接下来我要自己实现一个AOP框架!`(*∩_∩*)′

posted @ 2016-12-23 09:43  zhyonk  阅读(253)  评论(0)    收藏  举报