Skip to content

Commit

Permalink
JDK动态代理
Browse files Browse the repository at this point in the history
  • Loading branch information
DerekYRC committed Dec 6, 2020
1 parent 5839e17 commit c9720c3
Show file tree
Hide file tree
Showing 11 changed files with 270 additions and 1 deletion.
1 change: 0 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@
* [切点表达式](#切点表达式)
* [JDK动态代理](#JDK动态代理)
* [CGLib动态代理](#CGLib动态代理)
* [织入方法判断](#织入方法判断)
* [动态代理融入bean生命周期](#动态代理融入bean生命周期)


Expand Down
25 changes: 25 additions & 0 deletions changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -692,7 +692,32 @@ public class PointcutExpressionTest {
}
```

## 切点表达式
> 分支:jdk-dynamic-proxy
AopProxy是获取代理对象的抽象接口,JdkDynamicAopProxy的基于JDK动态代理的具体实现。TargetSource,被代理对象的封装。MethodInterceptor,方法拦截器,是AOP Alliance的"公民",顾名思义,可以拦截方法,可在被代理执行的方法前后增加代理行为。

测试;
```
public class DynamicProxyTest {
@Test
public void testJdkDynamicProxy() throws Exception {
WorldService worldService = new WorldServiceImpl();
AdvisedSupport advisedSupport = new AdvisedSupport();
TargetSource targetSource = new TargetSource(worldService);
WorldServiceInterceptor methodInterceptor = new WorldServiceInterceptor();
MethodMatcher methodMatcher = new AspectJExpressionPointcut("execution(* org.springframework.test.service.WorldService.explode(..))").getMethodMatcher();
advisedSupport.setTargetSource(targetSource);
advisedSupport.setMethodInterceptor(methodInterceptor);
advisedSupport.setMethodMatcher(methodMatcher);
WorldService proxy = (WorldService) new JdkDynamicAopProxy(advisedSupport).getProxy();
proxy.explode();
}
}
```



Expand Down
40 changes: 40 additions & 0 deletions src/main/java/org/springframework/aop/AdvisedSupport.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
package org.springframework.aop;

import org.aopalliance.intercept.MethodInterceptor;

/**
* @author derekyi
* @date 2020/12/6
*/
public class AdvisedSupport {

private TargetSource targetSource;

private MethodInterceptor methodInterceptor;

private MethodMatcher methodMatcher;

public TargetSource getTargetSource() {
return targetSource;
}

public void setTargetSource(TargetSource targetSource) {
this.targetSource = targetSource;
}

public MethodInterceptor getMethodInterceptor() {
return methodInterceptor;
}

public void setMethodInterceptor(MethodInterceptor methodInterceptor) {
this.methodInterceptor = methodInterceptor;
}

public MethodMatcher getMethodMatcher() {
return methodMatcher;
}

public void setMethodMatcher(MethodMatcher methodMatcher) {
this.methodMatcher = methodMatcher;
}
}
25 changes: 25 additions & 0 deletions src/main/java/org/springframework/aop/TargetSource.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package org.springframework.aop;

/**
* 被代理的目标对象
*
* @author derekyi
* @date 2020/12/6
*/
public class TargetSource {

private final Object target;

public TargetSource(Object target) {
this.target = target;
}

public Class<?>[] getTargetClass() {
return this.target.getClass().getInterfaces();
}

public Object getTarget() {
return this.target;
}

}
12 changes: 12 additions & 0 deletions src/main/java/org/springframework/aop/framework/AopProxy.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package org.springframework.aop.framework;

/**
* AOP代理抽象
*
* @author derekyi
* @date 2020/12/5
*/
public interface AopProxy {

Object getProxy();
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
package org.springframework.aop.framework;

import org.aopalliance.intercept.MethodInterceptor;
import org.springframework.aop.AdvisedSupport;

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

/**
* JDK动态代理
*
* @author derekyi
* @date 2020/12/5
*/
public class JdkDynamicAopProxy implements AopProxy, InvocationHandler {

private final AdvisedSupport advised;

public JdkDynamicAopProxy(AdvisedSupport advised) {
this.advised = advised;
}

/**
* 返回代理对象
*
* @return
*/
@Override
public Object getProxy() {
return Proxy.newProxyInstance(getClass().getClassLoader(), advised.getTargetSource().getTargetClass(), this);
}

@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
if (advised.getMethodMatcher().matches(method, advised.getTargetSource().getTarget().getClass())) {
//代理方法
MethodInterceptor methodInterceptor = advised.getMethodInterceptor();
return methodInterceptor.invoke(new ReflectiveMethodInvocation(advised.getTargetSource().getTarget(), method, args));
}
return method.invoke(advised.getTargetSource().getTarget(), args);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
package org.springframework.aop.framework;

import org.aopalliance.intercept.MethodInvocation;

import java.lang.reflect.AccessibleObject;
import java.lang.reflect.Method;

/**
* @author derekyi
* @date 2020/12/6
*/
public class ReflectiveMethodInvocation implements MethodInvocation {

private final Object target;

private final Method method;

private final Object[] arguments;

public ReflectiveMethodInvocation(Object target, Method method, Object[] arguments) {
this.target = target;
this.method = method;
this.arguments = arguments;
}

@Override
public Object proceed() throws Throwable {
return method.invoke(target, arguments);
}

@Override
public Method getMethod() {
return method;
}

@Override
public Object[] getArguments() {
return arguments;
}

@Override
public Object getThis() {
return target;
}

@Override
public AccessibleObject getStaticPart() {
return method;
}
}
34 changes: 34 additions & 0 deletions src/test/java/org/springframework/test/aop/DynamicProxyTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package org.springframework.test.aop;

import org.junit.Test;
import org.springframework.aop.AdvisedSupport;
import org.springframework.aop.MethodMatcher;
import org.springframework.aop.TargetSource;
import org.springframework.aop.aspectj.AspectJExpressionPointcut;
import org.springframework.aop.framework.JdkDynamicAopProxy;
import org.springframework.test.common.WorldServiceInterceptor;
import org.springframework.test.service.WorldService;
import org.springframework.test.service.WorldServiceImpl;

/**
* @author derekyi
* @date 2020/12/6
*/
public class DynamicProxyTest {

@Test
public void testJdkDynamicProxy() throws Exception {
WorldService worldService = new WorldServiceImpl();

AdvisedSupport advisedSupport = new AdvisedSupport();
TargetSource targetSource = new TargetSource(worldService);
WorldServiceInterceptor methodInterceptor = new WorldServiceInterceptor();
MethodMatcher methodMatcher = new AspectJExpressionPointcut("execution(* org.springframework.test.service.WorldService.explode(..))").getMethodMatcher();
advisedSupport.setTargetSource(targetSource);
advisedSupport.setMethodInterceptor(methodInterceptor);
advisedSupport.setMethodMatcher(methodMatcher);

WorldService proxy = (WorldService) new JdkDynamicAopProxy(advisedSupport).getProxy();
proxy.explode();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package org.springframework.test.common;

import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;

/**
* @author derekyi
* @date 2020/12/6
*/
public class WorldServiceInterceptor implements MethodInterceptor {
@Override
public Object invoke(MethodInvocation invocation) throws Throwable {
System.out.println("Do something before the earth explodes");
Object result = invocation.proceed();
System.out.println("Do something after the earth explodes");
return result;
}
}
10 changes: 10 additions & 0 deletions src/test/java/org/springframework/test/service/WorldService.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package org.springframework.test.service;

/**
* @author derekyi
* @date 2020/12/6
*/
public interface WorldService {

void explode();
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package org.springframework.test.service;

/**
* @author derekyi
* @date 2020/12/6
*/
public class WorldServiceImpl implements WorldService {

@Override
public void explode() {
System.out.println("The Earth is going to explode");
}
}

0 comments on commit c9720c3

Please sign in to comment.