Spring AOP编程的半自动和全自动编写代理

文章目录

    • Spring AOP编程的半自动和全自动编写代理
      • Spring编写代理:半自动
        • AOP联盟通知类型
        • 环绕通知
      • Spring编写代理:全自动

Spring AOP编程的半自动和全自动编写代理

Spring编写代理:半自动

  • 让spring 创建代理对象,从spring容器中手动的获取代理对象。注意:这里从Spring中获取到的是代理对象,而不是目标类对象

AOP联盟通知类型

  • AOP联盟为通知Advice定义了org.aopalliance.aop.Advice
  • Spring按照通知Advice在目标类方法的连接点位置,可以分为5类
    • 前置通知 org.springframework.aop.MethodBeforeAdvice
      • 在目标方法执行前实施增强
    • 后置通知 org.springframework.aop.AfterReturningAdvice
      • 在目标方法执行后实施增强
    • 环绕通知 org.aopalliance.intercept.MethodInterceptor(功能最强,可以实现其他类型的通知)
      • 在目标方法执行前后实施增强
    • 异常抛出通知 org.springframework.aop.ThrowsAdvice
      • 在方法抛出异常后实施增强
    • 引介通知 org.springframework.aop.IntroductionInterceptor
      • 在目标类中添加一些新的方法和属性
环绕通知,必须手动执行目标方法
try{
   //前置通知
   //执行目标方法
   //后置通知
} catch(){
   //抛出异常通知
}

环绕通知

我们重点来实现环绕通知,因为它的功能最强大

  • 编写目标类
    首先我们需要编写目标类
public interface UserService {

    public void addUser();
	public void updateUser();
	public void deleteUser();
}

public class UserServiceImpl implements UserService {
    @Override
    public void addUser() {
        System.out.println("addUser()");
    }

    @Override
    public void updateUser() {
        System.out.println("updateUser()");
    }

    @Override
    public void deleteUser() {
        System.out.println("deleteUser()");
    }
}

然后我们需要添加配置



    
    



然后进行测试看看

 @Test
    public void demo01(){
        String xmlPath = "spring_aop_proxy.xml";
        AbstractApplicationContext applicationContext = new ClassPathXmlApplicationContext(xmlPath);
        UserService userService = (UserService) applicationContext.getBean("userServiceId");
        userService.addUser();
        userService.updateUser();
        userService.deleteUser();
    }

Spring AOP编程的半自动和全自动编写代理_第1张图片

  • 编写切面类
    用于存放通知(也就是存放增强的代码)
/**
 * 切面类中确定通知,需要实现不同接口,接口就是规范,从而就确定方法名称。
 * * 采用“环绕通知” MethodInterceptor
 */
public class MyAspect implements MethodInterceptor {

	@Override
    public Object invoke(MethodInvocation mi) throws Throwable {
		
		System.out.println("before");
		
		//手动执行目标方法
		Object obj = mi.proceed();
		
		System.out.println("after");
		return obj;
	}
}

配置文件中添加切面类配置



    
    
    
    




  • 创建代理类
    之前我们用JDK动态代理还有CGLIB都是使用创建一个工厂类来返回代理。
    现在我们把创建一个工厂类来返回代理过程交给spring
    所以我们只需要添加一下Spring的配置,但是我们在Spring配置中配置这一个工厂类ProxyFactoryBean。所以这也就是为什么叫做半自动。


    
    
    
    
    
    
        
        
        
    




测试类

@Test
    public void demo02(){
        String xmlPath = "spring_aop_proxy.xml";
        AbstractApplicationContext applicationContext = new ClassPathXmlApplicationContext(xmlPath);
        UserService userService = (UserService) applicationContext.getBean("proxyServiceId");
        userService.addUser();
        userService.updateUser();
        userService.deleteUser();
    }

这里我们需要拿到代理类,然后调用它的方法。
Spring AOP编程的半自动和全自动编写代理_第2张图片

Spring编写代理:全自动

  • 从spring容器获得目标类,与半自动不同的是,这里从Spring获取到的是目标类。如果配置AOP,spring将自动生成代理。

我们首先要做的就是添加pom的依赖,添加spring aop的依赖还有aspectjweaver的依赖(用于确定目标类,aspectj 切入点表达式)

		
            org.springframework
            spring-aop
            4.2.0.RELEASE
        
        
            org.aspectj
            aspectjweaver
            1.9.3
        

然后我们要做的就是配置需要导入Spring AOP的命名空间
Spring AOP编程的半自动和全自动编写代理_第3张图片

然后我们还是需编写目标类还有切面类,都跟半自动的一样,这里就不写了,配置上也是需要加上的。不同的点在于最后创建代理对象的时候,是交给Spring帮我们自动生成代理,所以我们主要就是需要在配置中加入Spring AOP的配置。



    
    
    
    
    
    
        
        
    

然后就是测试

   @Test
    public void demo03(){
        String xmlPath = "spring_aop_proxy2.xml";
        AbstractApplicationContext applicationContext = new ClassPathXmlApplicationContext(xmlPath);
        UserService userService = (UserService) applicationContext.getBean("userServiceId");
        userService.addUser();
        userService.updateUser();
        userService.deleteUser();
    }

可以看到我们这里直接获取的是目标类
Spring AOP编程的半自动和全自动编写代理_第4张图片

你可能感兴趣的:(Spring)