spring整理(三)Spring AOP

Spring AOP

      AOP作为Spring中一个核心模块,通过代理模式在程序中架起了一层可自定义的拦截器

代理模式原理
  • 静态代理

    一个静态代理只能代理一个接口下的所有实现类

    代码


/**
 * 一个静态代理只能代理一个接口下的所有实现类
 */
public class GreetingProxyStatic implements Greeting{

	private GreetingImpl greetingImpl;
	
	public GreetingProxyStatic(GreetingImpl greetingImpl) {
		super();
		this.greetingImpl = greetingImpl;
	}
	@Override
	public void sayHello(String name) {
		before();
		greetingImpl.sayHello(name);
		after();
	}
	private void before() {
		System.out.println("before");
	}
	private void after() {
		System.out.println("before");
	}
}

class GreetingImpl implements Greeting{

	@Override
	public void sayHello(String name) {
		System.out.println("name");
	}
	
}
interface Greeting {
	void sayHello(String name);
}

class Client {
	public static void main(String[] args) {
		Greeting greetingProxyStatic = new GreetingProxyStatic(new GreetingImpl());
		greetingProxyStatic.sayHello("name");
		
	}
}

  • 动态代理
    一个动态代理可代理多个接口下的实现类,可通过配置proxy-target-class(false为JDK,true为CGlib)去切换

    • jdk代理
      jdk代理是Spring的默认选择,必须依赖接口

    代码


package com.td.mode;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

/**
 * 被代理的Class必须实现接口
 * spring默认使用JDK动态代理
 */
public class GreetingProxyDynamicJDK implements InvocationHandler{

	private Object target;
	public GreetingProxyDynamicJDK(Object target) {
		super();
		this.target = target;
	}
	
	@SuppressWarnings("unchecked")
	public <T> T getProxy() {
		return (T) Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), this);
	}
	
	@Override
	public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
		before();
		Object result = method.invoke(target, args);
		after();
		return result;
	}
	private void before() {
		System.out.println("before");
	}
	private void after() {
		System.out.println("before");
	}
}

class GreetingImpl implements Greeting{

	@Override
	public void sayHello(String name) {
		System.out.println("name");
	}
	
}
interface Greeting {
	void sayHello(String name);
}

class Client {
	public static void main(String[] args) {
		Greeting greetingProxyDynamicJDK = new GreetingProxyDynamicJDK(new GreetingImpl()).getProxy();
		greetingProxyDynamicJDK.sayHello("name");
	}
}
  • cglib代理
    jdk代理是Spring的默认选择,可直接代理任何类

代码


import java.lang.reflect.Method;

import org.springframework.cglib.proxy.Enhancer;
import org.springframework.cglib.proxy.MethodInterceptor;
import org.springframework.cglib.proxy.MethodProxy;

/**
 * 直接代理Class,被代理的Class不需要实现接口
 * spring-boot默认使用CGlib动态代理
 */
public class GreetingProxyDynamicCGlib implements MethodInterceptor{

	public static final GreetingProxyDynamicCGlib instance = new GreetingProxyDynamicCGlib();
	private GreetingProxyDynamicCGlib() {}
	
	
	@SuppressWarnings("unchecked")
	public <T> T getProxy(Class<T> cls) {
		return (T) Enhancer.create(cls, this);
	}
	
	@Override
	public Object intercept(Object target, Method method, Object[] args, MethodProxy proxy) throws Throwable {
		before();
		Object result = proxy.invokeSuper(target, args);
		after();
		return result;
	}
	private void before() {
		System.out.println("before");
	}
	private void after() {
		System.out.println("before");
	}
}
class GreetingImpl implements Greeting{

	@Override
	public void sayHello(String name) {
		System.out.println("name");
	}
	
}
interface Greeting {
	void sayHello(String name);
}

class Client {
	public static void main(String[] args) {
		Greeting greetingProxyDynamicCGlib = GreetingProxyDynamicCGlib.instance.getProxy(GreetingImpl.class);
		greetingProxyDynamicCGlib.sayHello("name");
	}
}


Spring AOP使用

直接上代码,笔者为了简单易读只写个Demo,读者可对其进一步封装,

  1. 扫描配置类

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.EnableAspectJAutoProxy;

import com.zgg.group2.rest.aspect.pojo.AspectDemo;

@Configuration
@EnableAspectJAutoProxy(proxyTargetClass=false)
@ComponentScan(basePackages="com.zgg.group2")
public class AspectConfig {
	@Bean
	public AspectDemo aspectDemo() {
		return new AspectDemo();
	}

}


  1. 拦截器

import org.aspectj.lang.ProceedingJoinPoint;
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;
import org.springframework.stereotype.Component;

import com.zgg.group2.rest.bean.ZgUser;

@Aspect
@Component
public class AspectDemo {
	//execution(任意返回值	url.任意类名(任意方法名))
//	@execution(* com.zgg.group2.rest.impl.*.save*(..))
	@Pointcut("execution(* com.zgg.group2.rest.impl.*.*(com.zgg.group2.rest.bean.ZgUser)) "
			+ "&& args(zgUser)")
	public void pointcutProxy(ZgUser zgUser){};
	
	@Before("pointcutProxy(zgUser)")
	public void before1(ZgUser zgUser) {
		
		System.out.println("execute method before1 and name = "+zgUser.getName());
	}
	
	@Before("pointcutProxy(zgUser)")
	public void before2(ZgUser zgUser) {
		System.out.println("execute method before2 and name = "+zgUser.getName());
	}
	
	@AfterReturning("pointcutProxy(zgUser)")
	public void afterReturning(ZgUser zgUser) {
		System.out.println("execute method afterReturning and name = "+zgUser.getName());
	}
	
	@AfterThrowing("pointcutProxy(zgUser)")
	public void afterThrowing(ZgUser zgUser) {
		System.out.println("execute method afterThrowing and name = "+zgUser.getName());
	}
	
	@Around("pointcutProxy(zgUser)")
	public void around(ProceedingJoinPoint jp, ZgUser zgUser) {
		try {
			System.out.println("around before and name = "+zgUser.getName());
			jp.proceed();
			System.out.println("around after");
		} catch (Throwable e) {
			e.printStackTrace();
		}
	}
}


 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

猜你喜欢

转载自blog.csdn.net/weixin_37481769/article/details/84344641