我实在接触spring的时候才接触到代理这个东西的,一直想整理一下笔记。

什么是代理模式:代理模式是通过代理对象访问目标对象,这样可以在目标对象基础上增强额外的功能。简单来说就是要创建一个新的对象,我们通过这个新的代理对象来操作目标对象。

例如我们租房子,我们可以直接和房东谈,房东其实就是我们的目标对象。但是有时候房东没空理你,所以他们就委托一个中介公司来代他和我们谈,这时候中介公司就可能会搞小动作,例如水电费收贵点,房租收贵1000,这就是所谓的增强操作。

代理的实现有4种:静态代理、jdk代理、cglib代理、Aspectj

1、静态代理

静态代理其实就是你自己写一个代理对象的类。就像下面的 Intermediary

package com.hongcheng.dubbo_api.producer;

/** 房东,一个接口 */
interface Landlord{
/** 出租房子 */
void rentHouse();
} /** 包租婆,具体实现 */
class LandlordWoman implements Landlord{
/** 出租房子 */
@Override
public void rentHouse(){
System.out.println("包租婆 ====> 房子800租给你了");
}
} /**
* 中介公司,这就是代理类
* */
class Intermediary implements Landlord{
private Landlord landlord;
public Intermediary(Landlord landlord) {
this.landlord = landlord;
}
/** 出租房子 */
@Override
public void rentHouse() {
System.out.println("中介公司 ====> 房子1000出租,我要赚200");
this.landlord.rentHouse();
}
} /**
* 测试
* */
public class StaticProxy {
public static void main(String[] args) {
// 要有一个包租婆
Landlord landlordWoman = new LandlordWoman();
// 包租婆委托给中介公司
Intermediary intermediary = new Intermediary(landlordWoman);
// 中介公司出租房子给各位韭菜
intermediary.rentHouse();
}
}

静态代理优点:

  1.   可以对目标类的每个方法都做不同的处理,进行更细致的处理。

静态代理缺点:

  1.   必须手动重写目标类的所有方法,如果目标类方法过多,编写会很麻烦。
  2.   如果目标类的方法修改了,代理类也必须同步修改,维护麻烦。

2、 jdk代理

jdk代理这是一种动态代理,不需要我们自己去撸这个一个代理类,由jdk的api来帮我们创建这个类,我们只是要设计一下要怎么代理就好

package com.hongcheng.dubbo_api;

import junit.framework.TestCase;

import java.io.IOException;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy; /** 房东,一个接口 */
interface Landlord{
/** 出租房子 */
void rentHouse();
} /** 包租婆,具体实现 */
class LandlordWoman implements Landlord {
/** 出租房子 */
@Override
public void rentHouse(){
System.out.println("包租婆 ====> 房子800租给你了");
}
}
/**
* 测试
* */
public class AppTest extends TestCase { public static void main(String[] args) throws IOException {
/** 我们的目标对象 */
LandlordWoman hongcheng = new LandlordWoman();
/** 我们目标对象的类加载器 */
ClassLoader classLoader = hongcheng.getClass().getClassLoader();
/** 我们目标对象实现的接口 */
Class<?>[] interfaces = hongcheng.getClass().getInterfaces();
/***
* 创建代理对象
* @param classLoader 类加载器,一般用我们目标对象的类加载器
* @param interfaces 我们目标对象实现的接口
* @param InvocationHandler 我们要对目标对象所有方法做的增强处理
* */
Object instance = Proxy.newProxyInstance(classLoader, interfaces, new InvocationHandler() {
/***
* 我们对目标对象的所有方法做的增强处理。
* @param proxy jdk帮我们创建的代理对象
* @param method 我们自己的目标对象的方法
* @param args 我们目标对象方法的调用参数
* */
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("代理开始");
System.out.println("中介公司 ====> 房子1000出租,我要赚200");
          // 这里要记住,invoke方法传入的对象是我们的目标对象,不是代理对象
Object invoke = method.invoke(hongcheng);
System.out.println("代理结束,结果===>" + invoke);
return invoke;
}
}); Landlord hong = (Landlord)instance;
hong.rentHouse();
// 这里阻塞程序是为了用工具将代理对象的class弄成.class文件
System.in.read();
} }

jdk代理优点:

  1.   只需要写一个对所有方法的增强处理就可以,jdk的api会自动处理所有方法,不管后面你怎么更改目标类,代理类的创建的代码都不用改变。

jdk代理缺点:

  1.     不能更细致的处理个别方法,所有方法的增强处理都是一样的。
  2.   目标类必须实现一个接口

让我们来看看jdk帮我们生成的代理对象是咋样的先:

$Proxy0 就是我们的代理对象:
特点:
继承Proxy类,实现了我们的Landlord接口
每个方法的调用实际上都是调用我们写的那个匿名内部类 InvocationHandler 的invoke方法,将我们原本的方法和参数传入。
package com.hongcheng.dubbo_api;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.lang.reflect.UndeclaredThrowableException; final class $Proxy0 extends Proxy implements Landlord {
private static Method m1;
private static Method m2;
private static Method m3;
private static Method m0; public $Proxy0(InvocationHandler var1) {
super(var1);
} static {
try {
m1 = Class.forName("java.lang.Object").getMethod("equals", Class.forName("java.lang.Object"));
m2 = Class.forName("java.lang.Object").getMethod("toString");
m3 = Class.forName("com.hongcheng.dubbo_api.Landlord").getMethod("rentHouse");
m0 = Class.forName("java.lang.Object").getMethod("hashCode");
} catch (NoSuchMethodException var2) {
throw new NoSuchMethodError(var2.getMessage());
} catch (ClassNotFoundException var3) {
throw new NoClassDefFoundError(var3.getMessage());
}
} public final boolean equals(Object var1) {
try {
return (Boolean)super.h.invoke(this, m1, new Object[]{var1});
} catch (RuntimeException | Error var3) {
throw var3;
} catch (Throwable var4) {
throw new UndeclaredThrowableException(var4);
}
} public final String toString() {
try {
return (String)super.h.invoke(this, m2, (Object[])null);
} catch (RuntimeException | Error var2) {
throw var2;
} catch (Throwable var3) {
throw new UndeclaredThrowableException(var3);
}
} public final int hashCode() {
try {
return (Integer)super.h.invoke(this, m0, (Object[])null);
} catch (RuntimeException | Error var2) {
throw var2;
} catch (Throwable var3) {
throw new UndeclaredThrowableException(var3);
}
} public final void rentHouse() {
try {
super.h.invoke(this, m3, (Object[])null);
} catch (RuntimeException | Error var2) {
throw var2;
} catch (Throwable var3) {
throw new UndeclaredThrowableException(var3);
}
}
}

匿名内部类,增强方法的实现。

package com.hongcheng.dubbo_api;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method; final class AppTest$1 implements InvocationHandler {
AppTest$1(LandlordWoman var1) {
this.val$hongcheng = var1;
} public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("代理开始");
System.out.println("中介公司 ====> 房子1000出租,我要赚200");
Object invoke = method.invoke(this.val$hongcheng);
System.out.println("代理结束,结果===>" + invoke);
return invoke;
}
}

3、cglib代理

cglib 就是  Code Generator Library  ,是一个强大的、高性能的代码生成库。其被广泛应用于AOP框架(Spring、dynaop)中,用以提供方法拦截操作。Hibernate作为一个比较受欢迎的ORM框架,同样使用CGLIB来代理单端(多对一和一对一)关联(延迟提取集合使用的另一种机制)。

要用cglib需要引入jar包,这里我用maven

<dependency>
<groupId>cglib</groupId>
<artifactId>cglib</artifactId>
<version>3.3.0</version>
</dependency>
package com.hongcheng.dubbo_api;

import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy; import java.io.IOException;
import java.lang.reflect.Method;
/** 房东,一个接口 */
interface Landlord{
/** 出租房子 */
void rentHouse();
}
/** 包租婆,具体实现 */
class LandlordWoman implements Landlord {
/** 出租房子 */
@Override
public void rentHouse(){
System.out.println("包租婆 ====> 房子800租给你了");
}
public final void finalMethod(){
System.out.println("finalMethod ====> 执行了");
}
public static void staticMethod(){
System.out.println("staticMethod ====> 执行了");
}
public void privateMethod1(){
System.out.println("privateMethod1 ====> 执行了");
this.privateMethod2();
}
private void privateMethod2(){
System.out.println("privateMethod2 ====> 执行了");
}
}
/***
* 测试
* */
public class CglibProxy {
public static void main(String[] args) throws IOException {
// 一个很重要的对象,用来生成代理对象,翻译过来就是“增强器”,和jdk代理的Proxy类似功能
Enhancer enhancer = new Enhancer();
// 设置代理对象的父类,这是必须步骤
enhancer.setSuperclass(LandlordWoman.class);
// 设置回调,其实就是增强处理对象,每次调用代理的方法,都会回调调用intercept方法
enhancer.setCallback(new MethodInterceptor() {
/**
* @param proxyObj 代理对象
* @param method 目标类的方法
* @param args 方法的参数
* @param methodProxy 代理对象的方法
* */
@Override
public Object intercept(Object proxyObj, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
System.out.println("代理开始");
System.out.println("中介公司 ====> 房子1000出租,我要赚200");
/**
* methodProxy.invokeSuper(proxyObj, args);
* 这种方法使用的是代理对象的方法调用,传入的也是代理对象,但最后还是调用我们自己的目标方法
* */
Object invoke = methodProxy.invokeSuper(proxyObj, args);
/**
* method.invoke(new LandlordWoman(), args);
* 这种方法使用的是我们目标对象的方法调用,传入的是目标对象,需要自己传入一个目标类的实例
* */
// Object invoke2 = method.invoke(new LandlordWoman(), args);
System.out.println("代理结束,结果===>" + invoke);
return invoke;
}
});
// 创建代理对象
LandlordWoman proxy= (LandlordWoman) enhancer.create();
proxy.rentHouse();
proxy.finalMethod();
proxy.privateMethod1();
proxy.staticMethod();
// 这里阻塞程序是为了用工具将代理对象的class弄成.class文件
System.in.read();
}
}

cglib代理优点:

  1.   只需要写一个对所有方法的增强处理就可以,cglib的api会自动处理所有方法,不管后面你怎么更改目标类,代理类的创建的代码都不用改变。
  2.   目标类可以不实现任务接口。
  3. Cglib包的底层是通过使用一个小而块的字节码处理框架ASM来转换字节码并生成新的类,性能上比较好

cglib代理缺点:

  1.     不能更细致的处理个别方法,所有方法的增强处理都是一样的。
  2.   目标类必须实现一个接口
  3. 代理的类不能为final,否则报错
  4. 目标对象的方法如果为final或static,那么就不会被拦截,即不会执行目标对象额外的业务方法.

看看他生成后的代理对象内容是怎样,代码有点长

代理对象是直接继承自我们的目标对象的。

//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by Fernflower decompiler)
// package com.hongcheng.dubbo_api; import java.lang.reflect.Method;
import net.sf.cglib.core.ReflectUtils;
import net.sf.cglib.core.Signature;
import net.sf.cglib.proxy.Callback;
import net.sf.cglib.proxy.Factory;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy; public class LandlordWoman$$EnhancerByCGLIB$$df42a67d extends LandlordWoman implements Factory {
private boolean CGLIB$BOUND;
public static Object CGLIB$FACTORY_DATA;
private static final ThreadLocal CGLIB$THREAD_CALLBACKS;
private static final Callback[] CGLIB$STATIC_CALLBACKS;
private MethodInterceptor CGLIB$CALLBACK_0;
private static Object CGLIB$CALLBACK_FILTER;
private static final Method CGLIB$rentHouse$0$Method;
private static final MethodProxy CGLIB$rentHouse$0$Proxy;
private static final Object[] CGLIB$emptyArgs;
private static final Method CGLIB$privateMethod1$1$Method;
private static final MethodProxy CGLIB$privateMethod1$1$Proxy;
private static final Method CGLIB$equals$2$Method;
private static final MethodProxy CGLIB$equals$2$Proxy;
private static final Method CGLIB$toString$3$Method;
private static final MethodProxy CGLIB$toString$3$Proxy;
private static final Method CGLIB$hashCode$4$Method;
private static final MethodProxy CGLIB$hashCode$4$Proxy;
private static final Method CGLIB$clone$5$Method;
private static final MethodProxy CGLIB$clone$5$Proxy; public LandlordWoman$$EnhancerByCGLIB$$df42a67d() {
CGLIB$BIND_CALLBACKS(this);
} static {
CGLIB$STATICHOOK1();
} public final boolean equals(Object var1) {
MethodInterceptor var10000 = this.CGLIB$CALLBACK_0;
if (var10000 == null) {
CGLIB$BIND_CALLBACKS(this);
var10000 = this.CGLIB$CALLBACK_0;
} if (var10000 != null) {
Object var2 = var10000.intercept(this, CGLIB$equals$2$Method, new Object[]{var1}, CGLIB$equals$2$Proxy);
return var2 == null ? false : (Boolean)var2;
} else {
return super.equals(var1);
}
} public final String toString() {
MethodInterceptor var10000 = this.CGLIB$CALLBACK_0;
if (var10000 == null) {
CGLIB$BIND_CALLBACKS(this);
var10000 = this.CGLIB$CALLBACK_0;
} return var10000 != null ? (String)var10000.intercept(this, CGLIB$toString$3$Method, CGLIB$emptyArgs, CGLIB$toString$3$Proxy) : super.toString();
} public final int hashCode() {
MethodInterceptor var10000 = this.CGLIB$CALLBACK_0;
if (var10000 == null) {
CGLIB$BIND_CALLBACKS(this);
var10000 = this.CGLIB$CALLBACK_0;
} if (var10000 != null) {
Object var1 = var10000.intercept(this, CGLIB$hashCode$4$Method, CGLIB$emptyArgs, CGLIB$hashCode$4$Proxy);
return var1 == null ? 0 : ((Number)var1).intValue();
} else {
return super.hashCode();
}
} protected final Object clone() throws CloneNotSupportedException {
MethodInterceptor var10000 = this.CGLIB$CALLBACK_0;
if (var10000 == null) {
CGLIB$BIND_CALLBACKS(this);
var10000 = this.CGLIB$CALLBACK_0;
} return var10000 != null ? var10000.intercept(this, CGLIB$clone$5$Method, CGLIB$emptyArgs, CGLIB$clone$5$Proxy) : super.clone();
} public Object newInstance(Class[] var1, Object[] var2, Callback[] var3) {
CGLIB$SET_THREAD_CALLBACKS(var3);
LandlordWoman$$EnhancerByCGLIB$$df42a67d var10000 = new LandlordWoman$$EnhancerByCGLIB$$df42a67d;
switch(var1.length) {
case 0:
var10000.<init>();
CGLIB$SET_THREAD_CALLBACKS((Callback[])null);
return var10000;
default:
throw new IllegalArgumentException("Constructor not found");
}
} public Object newInstance(Callback[] var1) {
CGLIB$SET_THREAD_CALLBACKS(var1);
LandlordWoman$$EnhancerByCGLIB$$df42a67d var10000 = new LandlordWoman$$EnhancerByCGLIB$$df42a67d();
CGLIB$SET_THREAD_CALLBACKS((Callback[])null);
return var10000;
} public Object newInstance(Callback var1) {
CGLIB$SET_THREAD_CALLBACKS(new Callback[]{var1});
LandlordWoman$$EnhancerByCGLIB$$df42a67d var10000 = new LandlordWoman$$EnhancerByCGLIB$$df42a67d();
CGLIB$SET_THREAD_CALLBACKS((Callback[])null);
return var10000;
} public void setCallback(int var1, Callback var2) {
switch(var1) {
case 0:
this.CGLIB$CALLBACK_0 = (MethodInterceptor)var2;
default:
}
} public final void rentHouse() {
MethodInterceptor var10000 = this.CGLIB$CALLBACK_0;
if (var10000 == null) {
CGLIB$BIND_CALLBACKS(this);
var10000 = this.CGLIB$CALLBACK_0;
} if (var10000 != null) {
var10000.intercept(this, CGLIB$rentHouse$0$Method, CGLIB$emptyArgs, CGLIB$rentHouse$0$Proxy);
} else {
super.rentHouse();
}
} public final void privateMethod1() {
MethodInterceptor var10000 = this.CGLIB$CALLBACK_0;
if (var10000 == null) {
CGLIB$BIND_CALLBACKS(this);
var10000 = this.CGLIB$CALLBACK_0;
} if (var10000 != null) {
var10000.intercept(this, CGLIB$privateMethod1$1$Method, CGLIB$emptyArgs, CGLIB$privateMethod1$1$Proxy);
} else {
super.privateMethod1();
}
} public void setCallbacks(Callback[] var1) {
this.CGLIB$CALLBACK_0 = (MethodInterceptor)var1[0];
} public Callback getCallback(int var1) {
CGLIB$BIND_CALLBACKS(this);
MethodInterceptor var10000;
switch(var1) {
case 0:
var10000 = this.CGLIB$CALLBACK_0;
break;
default:
var10000 = null;
} return var10000;
} public Callback[] getCallbacks() {
CGLIB$BIND_CALLBACKS(this);
return new Callback[]{this.CGLIB$CALLBACK_0};
} public static void CGLIB$SET_STATIC_CALLBACKS(Callback[] var0) {
CGLIB$STATIC_CALLBACKS = var0;
} public static void CGLIB$SET_THREAD_CALLBACKS(Callback[] var0) {
CGLIB$THREAD_CALLBACKS.set(var0);
} final int CGLIB$hashCode$4() {
return super.hashCode();
} final boolean CGLIB$equals$2(Object var1) {
return super.equals(var1);
} final Object CGLIB$clone$5() throws CloneNotSupportedException {
return super.clone();
} final String CGLIB$toString$3() {
return super.toString();
} public static MethodProxy CGLIB$findMethodProxy(Signature var0) {
String var10000 = var0.toString();
switch(var10000.hashCode()) {
case -1702390808:
if (var10000.equals("privateMethod1()V")) {
return CGLIB$privateMethod1$1$Proxy;
}
break;
case -508378822:
if (var10000.equals("clone()Ljava/lang/Object;")) {
return CGLIB$clone$5$Proxy;
}
break;
case 1194948270:
if (var10000.equals("rentHouse()V")) {
return CGLIB$rentHouse$0$Proxy;
}
break;
case 1826985398:
if (var10000.equals("equals(Ljava/lang/Object;)Z")) {
return CGLIB$equals$2$Proxy;
}
break;
case 1913648695:
if (var10000.equals("toString()Ljava/lang/String;")) {
return CGLIB$toString$3$Proxy;
}
break;
case 1984935277:
if (var10000.equals("hashCode()I")) {
return CGLIB$hashCode$4$Proxy;
}
} return null;
} static void CGLIB$STATICHOOK1() {
CGLIB$THREAD_CALLBACKS = new ThreadLocal();
CGLIB$emptyArgs = new Object[0];
Class var0 = Class.forName("com.hongcheng.dubbo_api.LandlordWoman$$EnhancerByCGLIB$$df42a67d");
Class var1;
Method[] var10000 = ReflectUtils.findMethods(new String[]{"equals", "(Ljava/lang/Object;)Z", "toString", "()Ljava/lang/String;", "hashCode", "()I", "clone", "()Ljava/lang/Object;"}, (var1 = Class.forName("java.lang.Object")).getDeclaredMethods());
CGLIB$equals$2$Method = var10000[0];
CGLIB$equals$2$Proxy = MethodProxy.create(var1, var0, "(Ljava/lang/Object;)Z", "equals", "CGLIB$equals$2");
CGLIB$toString$3$Method = var10000[1];
CGLIB$toString$3$Proxy = MethodProxy.create(var1, var0, "()Ljava/lang/String;", "toString", "CGLIB$toString$3");
CGLIB$hashCode$4$Method = var10000[2];
CGLIB$hashCode$4$Proxy = MethodProxy.create(var1, var0, "()I", "hashCode", "CGLIB$hashCode$4");
CGLIB$clone$5$Method = var10000[3];
CGLIB$clone$5$Proxy = MethodProxy.create(var1, var0, "()Ljava/lang/Object;", "clone", "CGLIB$clone$5");
var10000 = ReflectUtils.findMethods(new String[]{"rentHouse", "()V", "privateMethod1", "()V"}, (var1 = Class.forName("com.hongcheng.dubbo_api.LandlordWoman")).getDeclaredMethods());
CGLIB$rentHouse$0$Method = var10000[0];
CGLIB$rentHouse$0$Proxy = MethodProxy.create(var1, var0, "()V", "rentHouse", "CGLIB$rentHouse$0");
CGLIB$privateMethod1$1$Method = var10000[1];
CGLIB$privateMethod1$1$Proxy = MethodProxy.create(var1, var0, "()V", "privateMethod1", "CGLIB$privateMethod1$1");
} final void CGLIB$rentHouse$0() {
super.rentHouse();
} private static final void CGLIB$BIND_CALLBACKS(Object var0) {
LandlordWoman$$EnhancerByCGLIB$$df42a67d var1 = (LandlordWoman$$EnhancerByCGLIB$$df42a67d)var0;
if (!var1.CGLIB$BOUND) {
var1.CGLIB$BOUND = true;
Object var10000 = CGLIB$THREAD_CALLBACKS.get();
if (var10000 == null) {
var10000 = CGLIB$STATIC_CALLBACKS;
if (var10000 == null) {
return;
}
} var1.CGLIB$CALLBACK_0 = (MethodInterceptor)((Callback[])var10000)[0];
} } final void CGLIB$privateMethod1$1() {
super.privateMethod1();
}
}

增强内部类的代码

//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by Fernflower decompiler)
// package com.hongcheng.dubbo_api; import java.lang.reflect.Method;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy; final class CglibProxy$1 implements MethodInterceptor {
CglibProxy$1() {
} public Object intercept(Object proxyObj, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
System.out.println("代理开始");
System.out.println("中介公司 ====> 房子1000出租,我要赚200");
Object invoke = methodProxy.invokeSuper(proxyObj, args);
System.out.println("代理结束,结果===>" + invoke);
return invoke;
}
}

在Spring的AOP编程中:
  如果加入容器的目标对象有实现接口,用JDK代理
  如果目标对象没有实现接口,用Cglib代理

  

4、Aspectj

Aspectj实际上他是一种静态代理,因为Aspectj是在编译代码的时候,将你的增强代码写入你的业务代码中,而不是去创建一个代理类。

  1. Aspectj并不是动态的在运行时生成代理类,而是在编译的时候就植入代码到class文件
  2. 由于是静态织入的,所以性能相对来说比较好
  3. Aspectj不受类的特殊限制,不管方法是private、或者static、或者final的,都可以代理
  4. Aspectj不会代理除了限定方法之外任何其他诸如toString(),clone()等方法

Aspectj的使用方法我实在是找不到,等以后找到了再补上吧

注意,像我们下面这种常常在spring中写的aop代码,使用的是jdk代理或者cglib代理,虽然用了Aspectj的注解,但仍然用的是jdk动态代理,或者cglib动态代理。

//声明这是一个组件
@Component
//声明这是一个切面Bean
@Aspect
@Slf4j
public class ServiceAspect { //配置切入点,该方法无方法体,主要为方便同类中其他方法使用此处配置的切入点
@Pointcut("execution(* com.hdj.learn.spring.aop.service..*(..))")
public void aspect() {
} /*
* 配置前置通知,使用在方法aspect()上注册的切入点
* 同时接受JoinPoint切入点对象,可以没有该参数
*/
@Before("aspect()")
public void before(JoinPoint joinPoint) {
log.info("before " + joinPoint);
} //配置后置通知,使用在方法aspect()上注册的切入点
@After("aspect()")
public void after(JoinPoint joinPoint) {
log.info("after " + joinPoint);
} //配置环绕通知,使用在方法aspect()上注册的切入点
@Around("aspect()")
public void around(JoinPoint joinPoint) {
long start = System.currentTimeMillis();
try {
((ProceedingJoinPoint) joinPoint).proceed();
long end = System.currentTimeMillis();
log.info("around " + joinPoint + "\tUse time : " + (end - start) + " ms!");
} catch (Throwable e) {
long end = System.currentTimeMillis();
log.info("around " + joinPoint + "\tUse time : " + (end - start) + " ms with exception : " + e.getMessage());
}
} //配置后置返回通知,使用在方法aspect()上注册的切入点
@AfterReturning("aspect()")
public void afterReturn(JoinPoint joinPoint) {
log.info("afterReturn " + joinPoint);
} //配置抛出异常后通知,使用在方法aspect()上注册的切入点
@AfterThrowing(pointcut = "aspect()", throwing = "ex")
public void afterThrow(JoinPoint joinPoint, Exception ex) {
log.info("afterThrow " + joinPoint + "\t" + ex.getMessage());
} }

关于怎么获取动态代理生成的class对象的.class文件,参考下面这两篇文章吧:

https://www.cnblogs.com/dengrong/p/10622594.html

http://www.mamicode.com/info-detail-2242036.html

注意看怎么使用       java -classpath sa-jdi.jar "sun.jvm.hotspot.HSDB"      和         jps -l      就行了,其他方法使用了,都没卵用,就HSDB这个东西可以生成class文件

java代理,静态代理、jdk代理、cglib代理、Aspectj的更多相关文章

  1. Java代理(静态/动态 JDK,cglib)

    Java的代理模式是应用非常广泛的设计模式之一,也叫作委托模式,其目的就是为其他的对象提供一个代理以控制对某个对象的访问和使用,代理类负责为委托类预处理消息,过滤消息并转发消息,以及对消息执行后续处理 ...

  2. 分享知识-快乐自己:三种代理(静态、JDK、CGlib 代理)

    1):代理模式(静态代理)点我下载三种模式源码 代理模式是常用设计模式的一种,我们在软件设计时常用的代理一般是指静态代理,也就是在代码中显式指定的代理. 静态代理由 业务实现类.业务代理类 两部分组成 ...

  3. 《Proxy系列专题》:代理模式(静态、JDK、CGLib)

    <Proxy系列专题>:代理模式(静态.JDK.CGLib)使用 现象:在如今互联网时代,项目的复杂度不断的提升,有些场景下需要一定的设计优化来支撑业务的扩展,如为了不改动原始类,但需要对 ...

  4. 静态代理、动态代理和cglib代理

    转:https://www.cnblogs.com/cenyu/p/6289209.html 代理(Proxy)是一种设计模式,提供了对目标对象另外的访问方式;即通过代理对象访问目标对象.这样做的好处 ...

  5. 【Java】代理模式,静态代理和动态代理(基于JDK或CGLib)

    当我们需要在一个方法之前或之后添加一段逻辑时,自然会想到使用代理类.代理类帮我们代理了实际类的调用,然后可以在实际调用之前和之后添加一些逻辑,从而不浸入实际类. 拓展:由于代理类能在实际类调用之前和之 ...

  6. Java三种代理模式:静态代理、动态代理和cglib代理

    一.代理模式介绍 代理模式是一种设计模式,提供了对目标对象额外的访问方式,即通过代理对象访问目标对象,这样可以在不修改原目标对象的前提下,提供额外的功能操作,扩展目标对象的功能. 简言之,代理模式就是 ...

  7. Spring的代理模式(静态,JDK,CGLIB)

    一.静态代理   1.定义业务接口 public interface Subject { void doSomeThing(); }   2.真实业务类实现接口 public class RealSu ...

  8. java 动态代理模式(jdk和cglib)

    package proxy.dynamicproxy; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Met ...

  9. 【java高级编程】JDK和CGLIB动态代理区别

    转载:https://blog.csdn.net/yhl_jxy/article/details/80635012 前言 JDK动态代理实现原理(jdk8):https://blog.csdn.net ...

  10. java设计模式(一)动态代理模式,JDK与CGLIB分析

    -本想着这个知识点放到Spring Aop说说可能更合适一点,但因为上一篇有所提到就简单分析下,不足之处请多多评论留言,相互学习,有所提高才是关键! 什么是代理模式: 记得有本24种设计模式的书讲到代 ...

随机推荐

  1. 03 . Python入门之运算符

    一.什么是运算符? 举个简单的例子** 4 +5 = 9 . 例子中,4** 和 5 被称为操作数,"+" 称为运算符. Python语言支持以下类型的运算符: [算术运算符] [ ...

  2. Java实现 LeetCode 387 字符串中的第一个唯一字符

    387. 字符串中的第一个唯一字符 给定一个字符串,找到它的第一个不重复的字符,并返回它的索引.如果不存在,则返回 -1. 案例: s = "leetcode" 返回 0. s = ...

  3. Java实现 蓝桥杯VIP 算法训练 整数平均值

    题目描述 编写函数,求包含n个元素的整数数组中元素的平均值.要求在函数内部使用指针操纵数组元素,其中n个整数从键盘输入,输出为其平均值. (样例说明:5为输入数据的个数,3 4 0 0 2 是以空格隔 ...

  4. Java实现 蓝桥杯VIP 算法训练 数对

    算法训练 数对 时间限制:1.0s 内存限制:512.0MB 问题描述 编写一个程序,该程序从用户读入一个整数,然后列出所有的数对,每个数对的乘积即为该数. 输入格式:输入只有一行,即一个整数. 输出 ...

  5. SQL Server实现 LeetCode 177 第N高的薪水

    177. 第N高的薪水 编写一个 SQL 查询,获取 Employee 表中第 n 高的薪水(Salary). +----+--------+ | Id | Salary | +----+------ ...

  6. Java实现 蓝桥杯VIP 算法提高 最小乘积(提高型)

    算法提高 最小乘积(提高型) 时间限制:1.0s 内存限制:512.0MB 问题描述 给两组数,各n个. 请调整每组数的排列顺序,使得两组数据相同下标元素对应相乘,然后相加的和最小.要求程序输出这个最 ...

  7. Java实现 洛谷 P1422 小玉家的电费

    import java.util.*; public class Main { public static void main(String[] args) { Scanner in = new Sc ...

  8. java实现第七届蓝桥杯方格填数

    方格填数 题目描述 如下的10个格子 +--+--+--+ | | | | +--+--+--+--+ | | | | | +--+--+--+--+ | | | | +--+--+--+ (如果显示 ...

  9. zabbix 中文乱码

    环境 zabbix 3.4.7 centos 7.4 问题现象 zabbix 中文乱码     解决方法 1.先准备一个字体包    Windows路径 C:\Windows\Fonts\simkai ...

  10. Andorid中写文件后在电脑上看不到的解决办法

    每次通过输出流往SD卡写入文件,连接上电脑,用MTP的方式模拟一个移动磁盘,打开磁盘却没有这样一个文件,而通过adb的方式查看就有,造成这个现象的原因是,每次写入之后,MTP的数据库并没有更新,因为更 ...