-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
刘义
committed
Feb 17, 2019
1 parent
493e057
commit f851ea9
Showing
10 changed files
with
349 additions
and
1 deletion.
There are no files selected for viewing
22 changes: 22 additions & 0 deletions
22
framework/src/main/java/com/custom/framework/annotation/Aspect.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
package com.custom.framework.annotation; | ||
|
||
import java.lang.annotation.Annotation; | ||
import java.lang.annotation.ElementType; | ||
import java.lang.annotation.Retention; | ||
import java.lang.annotation.RetentionPolicy; | ||
import java.lang.annotation.Target; | ||
|
||
/** | ||
* @author liuyi | ||
* @date 2019/2/16 | ||
*/ | ||
|
||
@Target(ElementType.TYPE) | ||
@Retention(RetentionPolicy.RUNTIME) | ||
public @interface Aspect { | ||
/** | ||
* 注解 | ||
* @return | ||
*/ | ||
Class<? extends Annotation> value(); | ||
} |
32 changes: 32 additions & 0 deletions
32
framework/src/main/java/com/custom/framework/aspect/ControllerAspect.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
package com.custom.framework.aspect; | ||
|
||
import com.custom.framework.proxy.AspectProxy; | ||
import org.slf4j.Logger; | ||
import org.slf4j.LoggerFactory; | ||
|
||
import java.lang.reflect.Method; | ||
|
||
/** | ||
* @author liuyi | ||
* @date 2019/2/17 | ||
*/ | ||
public class ControllerAspect extends AspectProxy { | ||
|
||
private static final Logger logger = LoggerFactory.getLogger(ControllerAspect.class); | ||
|
||
private long begin; | ||
|
||
@Override | ||
public void before(Class<?> cls, Method method, Object[] params) throws Throwable { | ||
logger.debug("---------- begin ----------"); | ||
logger.debug(String.format("class: %s", cls.getName())); | ||
logger.debug(String.format("method: %s", method.getName())); | ||
begin = System.currentTimeMillis(); | ||
} | ||
|
||
@Override | ||
public void after(Class<?> cls, Method method, Object[] params) throws Throwable { | ||
logger.debug(String.format("time: %dms", System.currentTimeMillis() - begin)); | ||
logger.debug("---------- end ----------"); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
93 changes: 93 additions & 0 deletions
93
framework/src/main/java/com/custom/framework/proxy/AopHelper.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,93 @@ | ||
package com.custom.framework.proxy; | ||
|
||
import com.custom.framework.annotation.Aspect; | ||
import com.custom.framework.helper.BeanHelper; | ||
import com.custom.framework.helper.ClassHelper; | ||
import org.slf4j.Logger; | ||
import org.slf4j.LoggerFactory; | ||
|
||
import java.lang.annotation.Annotation; | ||
import java.util.ArrayList; | ||
import java.util.HashMap; | ||
import java.util.HashSet; | ||
import java.util.List; | ||
import java.util.Map; | ||
import java.util.Set; | ||
|
||
/** | ||
* 初始化 AOP 框架 | ||
* | ||
* @author huangyong | ||
* @since 1.0 | ||
*/ | ||
public class AopHelper { | ||
private static final Logger logger = LoggerFactory.getLogger(AopHelper.class); | ||
|
||
static { | ||
try { | ||
// 创建 Proxy Map(用于 存放代理类 与 目标类列表 的映射关系) | ||
Map<Class<?>, Set<Class<?>>> proxyMap = createProxyMap(); | ||
// 创建 Target Map(用于 存放目标类 与 代理类列表 的映射关系) | ||
Map<Class<?>, List<Proxy>> targetMap = createTargetMap(proxyMap); | ||
// 遍历 Target Map | ||
for (Map.Entry<Class<?>, List<Proxy>> targetEntry : targetMap.entrySet()) { | ||
// 分别获取 map 中的 key 与 value | ||
Class<?> targetClass = targetEntry.getKey(); | ||
List<Proxy> proxyList = targetEntry.getValue(); | ||
// 创建代理实例 | ||
Object proxyInstance = ProxyManager.createProxy(targetClass, proxyList); | ||
// 用代理实例覆盖目标实例,并放入 Bean 容器中 | ||
BeanHelper.setBeanMap(targetClass, proxyInstance); | ||
} | ||
} catch (Exception e) { | ||
logger.error("aop failure",e); | ||
} | ||
} | ||
|
||
private static Map<Class<?>, Set<Class<?>>> createProxyMap() throws Exception { | ||
Map<Class<?>, Set<Class<?>>> proxyMap = new HashMap<>(); | ||
Set<Class<?>> proxyClassSet = ClassHelper.getClassSetBySuper(AspectProxy.class); | ||
for(Class<?> proxyClass : proxyClassSet) { | ||
if (proxyClass.isAnnotationPresent(Aspect.class)) { | ||
Aspect aspect = proxyClass.getAnnotation(Aspect.class); | ||
Set<Class<?>> targetClassSet = createTargetClassSet(aspect); | ||
proxyMap.put(proxyClass, targetClassSet); | ||
} | ||
} | ||
return proxyMap; | ||
} | ||
|
||
|
||
private static Set<Class<?>> createTargetClassSet(Aspect aspect) throws Exception { | ||
Set<Class<?>> targetClassSet = new HashSet<>(); | ||
Class<? extends Annotation> annotation = aspect.value(); | ||
if (annotation != null && !annotation.equals(Aspect.class)) { | ||
targetClassSet.addAll(ClassHelper.getClassSetByAnnotation(annotation)); | ||
} | ||
return targetClassSet; | ||
} | ||
|
||
private static Map<Class<?>, List<Proxy>> createTargetMap(Map<Class<?>, Set<Class<?>>> proxyMap) throws Exception { | ||
Map<Class<?>, List<Proxy>> targetMap = new HashMap<Class<?>, List<Proxy>>(); | ||
// 遍历 Proxy Map | ||
for (Map.Entry<Class<?>, Set<Class<?>>> proxyEntry : proxyMap.entrySet()) { | ||
// 分别获取 map 中的 key 与 value | ||
Class<?> proxyClass = proxyEntry.getKey(); | ||
Set<Class<?>> targetClassSet = proxyEntry.getValue(); | ||
// 遍历目标类列表 | ||
for (Class<?> targetClass : targetClassSet) { | ||
// 创建代理类(切面类)实例 | ||
Proxy baseAspect = (Proxy) proxyClass.newInstance(); | ||
// 初始化 Target Map | ||
if (targetMap.containsKey(targetClass)) { | ||
targetMap.get(targetClass).add(baseAspect); | ||
} else { | ||
List<Proxy> baseAspectList = new ArrayList<Proxy>(); | ||
baseAspectList.add(baseAspect); | ||
targetMap.put(targetClass, baseAspectList); | ||
} | ||
} | ||
} | ||
return targetMap; | ||
} | ||
} |
65 changes: 65 additions & 0 deletions
65
framework/src/main/java/com/custom/framework/proxy/AspectProxy.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
package com.custom.framework.proxy; | ||
|
||
import org.slf4j.Logger; | ||
import org.slf4j.LoggerFactory; | ||
|
||
import java.lang.reflect.Method; | ||
|
||
/** | ||
* @author liuyi | ||
* @date 2019/2/17 | ||
*/ | ||
public abstract class AspectProxy implements Proxy{ | ||
|
||
private static final Logger logger = LoggerFactory.getLogger(AspectProxy.class); | ||
|
||
@Override | ||
public final Object doProxy(ProxyChain proxyChain) throws Throwable { | ||
Object result = null; | ||
|
||
Class<?> cls = proxyChain.getTargetClass(); | ||
Method method = proxyChain.getTargetMethod(); | ||
Object[] params = proxyChain.getMethodParams(); | ||
try { | ||
if (intercept(cls, method, params)) { | ||
before(cls, method, params); | ||
result = proxyChain.doProxyChain(); | ||
after(cls, method, params); | ||
} else { | ||
result = proxyChain.doProxyChain(); | ||
} | ||
} catch (Exception e) { | ||
logger.error("proxy failure", e); | ||
error(cls, method, params, e); | ||
throw e; | ||
} finally { | ||
end(); | ||
} | ||
return result; | ||
} | ||
|
||
public boolean intercept(Class<?> cls, Method method, Object[] params) throws Throwable { | ||
return true; | ||
} | ||
|
||
public void begin() { | ||
|
||
} | ||
|
||
public void before(Class<?> cls, Method method, Object[] params) throws Throwable { | ||
|
||
} | ||
|
||
public void after(Class<?> cls, Method method, Object[] params) throws Throwable { | ||
|
||
} | ||
|
||
public void error(Class<?> cls, Method method,Object[] params, Throwable e) { | ||
|
||
} | ||
|
||
public void end() { | ||
|
||
} | ||
|
||
} |
10 changes: 10 additions & 0 deletions
10
framework/src/main/java/com/custom/framework/proxy/Proxy.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
package com.custom.framework.proxy; | ||
|
||
/** | ||
* @author liuyi | ||
* @date 2019/2/16 | ||
*/ | ||
public interface Proxy { | ||
|
||
Object doProxy(ProxyChain proxyChain) throws Throwable; | ||
} |
60 changes: 60 additions & 0 deletions
60
framework/src/main/java/com/custom/framework/proxy/ProxyChain.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,60 @@ | ||
package com.custom.framework.proxy; | ||
|
||
import net.sf.cglib.proxy.MethodProxy; | ||
|
||
import java.lang.reflect.Method; | ||
import java.util.ArrayList; | ||
import java.util.List; | ||
|
||
/** | ||
* @author liuyi | ||
* @date 2019/2/16 | ||
*/ | ||
public class ProxyChain { | ||
|
||
private final Class<?> targetClass; | ||
|
||
private final Object targetObject; | ||
|
||
private final Method targetMethod; | ||
|
||
private final MethodProxy methodProxy; | ||
|
||
private final Object[] methodParams; | ||
|
||
private List<Proxy> proxyList = new ArrayList<>(); | ||
|
||
private int proxyIndex = 0; | ||
|
||
public ProxyChain(Class<?> targetClass, Object targetObject, Method targetMethod, | ||
MethodProxy methodProxy, Object[] methodParams, List<Proxy> proxyList) { | ||
this.targetClass = targetClass; | ||
this.targetObject = targetObject; | ||
this.targetMethod = targetMethod; | ||
this.methodProxy = methodProxy; | ||
this.methodParams = methodParams; | ||
this.proxyList = proxyList; | ||
} | ||
|
||
public Object[] getMethodParams() { | ||
return methodParams; | ||
} | ||
|
||
public Class<?> getTargetClass() { | ||
return targetClass; | ||
} | ||
|
||
public Method getTargetMethod() { | ||
return targetMethod; | ||
} | ||
|
||
public Object doProxyChain() throws Throwable { | ||
Object methodResult; | ||
if (proxyIndex < proxyList.size()) { | ||
methodResult = proxyList.get(proxyIndex++).doProxy(this); | ||
} else { | ||
methodResult = methodProxy.invokeSuper(targetObject, methodParams); | ||
} | ||
return methodResult; | ||
} | ||
} |
25 changes: 25 additions & 0 deletions
25
framework/src/main/java/com/custom/framework/proxy/ProxyManager.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
package com.custom.framework.proxy; | ||
|
||
import net.sf.cglib.proxy.Enhancer; | ||
import net.sf.cglib.proxy.MethodInterceptor; | ||
import net.sf.cglib.proxy.MethodProxy; | ||
|
||
import java.lang.reflect.Method; | ||
import java.util.List; | ||
|
||
/** | ||
* @author liuyi | ||
* @date 2019/2/17 | ||
*/ | ||
public class ProxyManager { | ||
|
||
public static <T> T createProxy(final Class<?> targetClass, final List<Proxy> proxyList) { | ||
return (T) Enhancer.create(targetClass, new MethodInterceptor() { | ||
@Override | ||
public Object intercept(Object targetObject, Method targetMethod, Object[] methodParams, MethodProxy methodProxy) throws Throwable { | ||
return new ProxyChain(targetClass, targetObject, targetMethod, | ||
methodProxy, methodParams, proxyList ); | ||
} | ||
}); | ||
} | ||
} |