Java Springaop

spring实现aop的原理

动态代理(有接口优先)

被代理对象必须要实现接口,才能残生代理对象,如果没有接口,将不能使用动态代理

cglib代理(无接口优先)

第三方代理技术,cglib代理可以对任何类生成代理,代理的原理是对目标对象进行继承代理,如果目标对象被final修饰,那么该类无法被cglib代理。

aop名词

Joinpoint(连接点):
Pointcut(切入点):
Advice(通知/增强):
Target(目标对象):
Weaving(织入):
Proxy(代理):

aspect(切面):
aop名词.png

spring中的aop演示

步骤:

1.导包4+2+2+2


spring包4+2+2+2.png

2.准备目标对象

public class UserServiceImpl implements     UserService {
@Override
public void save() {
    System.out.println("保存用户!");
}
@Override
public void delete() {
    System.out.println("删除用户!");
}
@Override
public void update() {
    System.out.println("更新用户!");
}
@Override
public void find() {
    System.out.println("查找用户!");
}
}

3.准备通知

    //通知类
public class MyAdvice {

    //前置通知->目标方法运行之前调用
    
    //后置通知(如果出现异常不会调用)->目标方法运行之后调用
    
    //环绕通知->在目标方法之前之后都调用
    
    //异常拦截通知->如果出现异常,就会调用
    
    //后置通知(无论是否出现异常都会调用)->在目标方法运行之后调用
    
    //----------------------------------
    
    
    //前置通知
    public void before() {
        System.out.println("这是前置通知!");
    }
    
    //后置通知
    public void afterReturning() {
        System.out.println("这是后置通知!如果出现异常不会调用");
    }
    
    //环绕通知
    public Object around(ProceedingJoinPoint pjp) throws Throwable {
                
        System.out.println("这是环绕通知之前的部分!");
        
        Object proceed = pjp.proceed();//调用目标方法
                
        System.out.println("这是环绕通知之后的部分!");
        
        return proceed;
    }
    //异常通知
    public void afterException() {
        System.out.println("这是异常通知!");
    }
    //后置通知
    public void after() {
        System.out.println("这是后置通知!(出现异常也会调用)");
    }
        
    
}

4.配置进行织入,将通知织入目标对象中
applicationContext.xml配置文件





    


    

    
        
        
        
        
        
        
        
        
        
        
        
        
        
        
    


5.测试

import javax.annotation.Resource;

import org.junit.Test;
import org.junit.runner.RunWith;

import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

import cn.lc.service.*;


@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:cn/lc/d_springaop/applicationContext.xml")
public class Demo {
    @Resource(name="userService")
    private User us;
    @Test
    public void fun1(){
    
        us.save();
        
    }
    
}
//输出
这是前置通知!
这是环绕通知之前的部分!
保存
这是后置通知!(出现异常也会调用)
这是环绕通知之后的部分!
这是后置通知!如果出现异常不会调用

spring注解方式的配置

1.导包
2.准备目标类
3.准备通知
4.配置applicationContext.xml文件





    


    

    


5.注解

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;

//通知类
@Aspect
public class MyAdvice {

    //前置通知
    @Before("execution(* cn.lc.service.*ServiceImpl.*(..))")
    public void before() {
        System.out.println("这是前置通知!");
    }
    
    //后置通知
    @AfterReturning("execution(* cn.lc.service.*ServiceImpl.*(..))")
    public void afterReturning() {
        System.out.println("这是后置通知!如果出现异常不会调用");
    }
    
    //环绕通知
    @Around("execution(* cn.lc.service.*ServiceImpl.*(..))")
    public Object around(ProceedingJoinPoint pjp) throws Throwable {
                
        System.out.println("这是环绕通知之前的部分!");
        
        Object proceed = pjp.proceed();//调用目标方法
                
        System.out.println("这是环绕通知之后的部分!");
        
        return proceed;
    }
    //异常通知
    
    @AfterThrowing("execution(* cn.lc.service.*ServiceImpl.*(..))")
    public void afterException() {
        System.out.println("这是异常通知!");
    }
    //后置通知
    @After("execution(* cn.lc.service.*ServiceImpl.*(..))")
    public void after() {
        System.out.println("这是后置通知!(出现异常也会调用)");
    }
}

测试

import javax.annotation.Resource;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

import cn.lc.service.*;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:cn/lc/e_annotationaop/applicationContext.xml")
public class Demo {
    @Resource(name="userService")
    private User us;
    @Test
    public void fun1(){ 
        us.save();  
    }   
}
//输出
这是环绕通知之前的部分!
这是前置通知!
保存
这是环绕通知之后的部分!
这是后置通知!(出现异常也会调用)
这是后置通知!如果出现异常不会调用

你可能感兴趣的:(Java Springaop)