常见叫法,面向切面编程,实际原理就是代理模式,即在调用方法做前置处理或后置处理
package com.finger.test.temp.aopstudy;
/**
* @Des:
* @Auther: 飞狐
* @Date: 2019/1/5
*/
public interface Star {
void sing();
}
package com.finger.test.temp.aopstudy;
import org.springframework.stereotype.Component;
/**
* @Des:
* @Auther: 飞狐
* @Date: 2019/1/5
*/
@Component("realStar")
public class RealStar implements Star {
@Override
public void sing(){
System.out.println("I love sing");
}
}
package com.finger.test.temp.aopstudy;
import org.springframework.stereotype.Component;
/**
* @Des: 静态代理类
* @Auther: 飞狐
* @Date: 2019/1/5
*/
@Component("proxyStar")
public class ProxyStar implements Star {
private Star star;
public ProxyStar(){
}
public ProxyStar(Star star) {
this.star = star;
}
@Override
public void sing(){
System.out.println("我在代理明星");
this.star.sing();
System.out.println("代言费用很贵");
}
}
/**
* 静态代理实现
*/
@Test
public void test1(){
Star realStar = new RealStar();
Star proxyStar = new ProxyStar(realStar);
proxyStar.sing();
}
package com.finger.test.temp.aopstudy;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
/**
* @Des: JDK动态代理方式
* @Auther: 飞狐
* @Date: 2019/1/5
*/
public class JdkDynamicProxyStar implements InvocationHandler {
private Object realStar;
public JdkDynamicProxyStar(Star star){
this.realStar = star;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable{
System.out.println("Hi");
Object object= method.invoke(realStar,args);
System.out.println("end");
return object;
}
public <T> T getInstance(){
return (T)Proxy.newProxyInstance(this.realStar.getClass().getClassLoader(),this.realStar.getClass().getInterfaces(),this);
}
}
/**
* JDK动态代理
*/
@Test
public void test2(){
Star realStar = new RealStar();
Star proxyStar = new JdkDynamicProxyStar(realStar).getInstance();
proxyStar.sing();
}
相对于静态代理,动态代理减少对业务接口的依赖,降低了代码耦合度;JDK动态代理实质是采用Invoke反射机制生成代理类,JDK 实现动态代理需要实现类通过接口定义业务方法
对于没有接口的类,则采用CGLIB代理进行实现动态代理,CGLIB 采用了非常底层的字节码技术,其原理是通过字节码技术为一个类创建子类,并在子类中采用方法拦截的技术拦截所有父类方法的调用,顺势织入横切逻辑。但因为采用的是继承,所以不能对final修饰的类进行代理
package com.finger.test.temp.aopstudy;
import org.springframework.cglib.proxy.Enhancer;
import org.springframework.cglib.proxy.MethodInterceptor;
import org.springframework.cglib.proxy.MethodProxy;
import java.lang.reflect.Method;
/**
* @Des: CGLIB动态代理方式
* @Auther: 飞狐
* @Date: 2019/1/5
*/
public class CGLIBDynamicProxyStar implements MethodInterceptor {
private Object realStar;
public CGLIBDynamicProxyStar(Star star){
this.realStar = star;
}
@Override
public Object intercept(Object var1, Method var2, Object[] var3, MethodProxy var4) throws Throwable{
System.out.println("Hi");
Object object = var4.invokeSuper(var1,var3);
System.out.println("end");
return object;
}
public <T> T getInstance(){
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(this.realStar.getClass());
enhancer.setCallback(this);
return (T) enhancer.create();
}
/**
* CGLIB动态代理方式
*/
@Test
public void test3(){
Star proxyStar = new CGLIBDynamicProxyStar(new RealStar()).getInstance();
proxyStar.sing();
}
}
package com.finger.test.temp.aopstudy;
/**
* @Des:
* @Auther: 飞狐
* @Date: 2019/1/5
*/
public interface SupperStar {
void sing();
}
package com.finger.test.temp.aopstudy;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;
/**
* @Des:
* @Auther: 飞狐
* @Date: 2019/1/5
*/
@Aspect
@Component
public class AopStar {
@Pointcut("execution (* com.finger.test.temp.aopstudy.SupperStar.*(..))")
public void hinihao(){
}
@Around("hinihao()")
public <T> T around(ProceedingJoinPoint joinPoint) throws Throwable{
System.out.println(joinPoint.getSignature().getName());
Object result = joinPoint.proceed();
System.out.println("哈哈哈哈哈");
return (T)result;
}
}
package com.finger.test.temp.aopstudy;
import com.finger.test.base.BaseSupport;
import org.junit.Test;
import org.springframework.beans.factory.annotation.Autowired;
/**
* @Des:
* @Auther: 飞狐
* @Date: 2019/1/5
*/
public class AopStarTest extends BaseSupport {
@Autowired
private SupperStar jiaStar;
@Test
public void test(){
jiaStar.sing();
}
}