007-搭建框架-开发AOP框架
一、代码地址
https://github.com/bjlhx15/smart-framework.git
二、代码编写
2.1、定义切面注解
增加Aspect注解
package com.lhx.smart.framework.annotation; import java.lang.annotation.*; @Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) public @interface Aspect { Class<? extends Annotation> value(); }
注意:通过@Target(ElementType.TYPE)来设置该注解只能用在类上,该注解包含一个名为value的属性,他是一个注解用来定义Controller这类注解。
在使用切面注解,需要搭建一个代理框架。如下
2.2、搭建代理框架
添加Proxy接口
package com.lhx.smart.framework.proxy; public interface Proxy { Object doProxy(ProxyChain proxyChain) throws Throwable; }
添加ProxyChain代理执行链
package com.lhx.smart.framework.proxy; import net.sf.cglib.proxy.MethodProxy; import java.lang.reflect.Method; import java.util.ArrayList; import java.util.List; 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<Proxy>(); 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; } }
注意MethodProxy是CGLib提供,需要增加注解POM
<dependency> <groupId>cglib</groupId> <artifactId>cglib</artifactId> <version>3.1</version> </dependency>
增加ProxyManager类
package com.lhx.smart.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; public class ProxyManager { public static <T> T createProxy(final Class<T> targetClass, final List<Proxy> proxyList) { return (T) Enhancer.create(targetClass, new MethodInterceptor() { public Object intercept(Object targetObject, Method targetMethod, Object[] objects, MethodProxy methodProxy) throws Throwable { return new ProxyChain(targetClass, targetObject, targetMethod, methodProxy, objects, proxyList).doProxyChain(); } }); } }
增加AspectProxy代理
package com.lhx.smart.framework.proxy; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.lang.reflect.Method; public abstract class AspectProxy implements Proxy{ private static final Logger logger= LoggerFactory.getLogger(AspectProxy.class); public Object doProxy(ProxyChain proxyChain) throws Throwable { Object result=null; Class<?> cls = proxyChain.getTargetClass(); Method method = proxyChain.getTargetMethod(); Object[] params = proxyChain.getMethodParams(); begin(); try { if(intercept(cls,method,params)){ before(cls,method,params); result = proxyChain.doProxyChain(); after(cls,method,params,result); }else{ result = proxyChain.doProxyChain(); } } catch (Exception e) { logger.error("proxy failure",e); error(cls,method,params,e); throw e; } finally { end(); } return result; } public void begin(){ } public boolean intercept(Class<?> cls,Method method,Object[] params) throws Throwable{ return true; } public void before(Class<?> cls,Method method,Object[] params) throws Throwable{ } public void after(Class<?> cls,Method method,Object[] params,Object result) throws Throwable{ } public void error(Class<?> cls,Method method,Object[] params,Throwable e){ } public void end(){ } }
增加一个实现
package com.lhx.chapter4.aspect; import com.lhx.smart.framework.annotation.Aspect; import com.lhx.smart.framework.annotation.Controller; import com.lhx.smart.framework.proxy.AspectProxy; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.lang.reflect.Method; @Aspect(Controller.class) 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-----"); begin = System.currentTimeMillis(); } @Override public void after(Class<?> cls, Method method, Object[] params, Object result) throws Throwable { logger.debug(String.valueOf(System.currentTimeMillis()-begin)); } }
2.3、加载AOP
增加AopHelper类
package com.lhx.smart.framework.helper; import com.lhx.smart.framework.annotation.Aspect; import com.lhx.smart.framework.proxy.AspectProxy; import com.lhx.smart.framework.proxy.Proxy; import com.lhx.smart.framework.proxy.ProxyManager; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import sun.util.resources.cldr.ti.CalendarData_ti_ER; import java.lang.annotation.Annotation; import java.util.*; public final class AopHelper { private static final Logger LOGGER = LoggerFactory.getLogger(AopHelper.class); static { try { Map<Class<?>, Set<Class<?>>> proxyMap = createProxyMap(); Map<Class<?>, List<Proxy>> targetMap = createTargetMap(proxyMap); for (Map.Entry<Class<?>, List<Proxy>> targetEntry : targetMap.entrySet()) { Class<?> targetClass = targetEntry.getKey(); List<Proxy> proxyList = targetEntry.getValue(); Object proxy=ProxyManager.createProxy(targetClass,proxyList); BeanHelper.setBean(targetClass,proxy); } } catch (Exception e) { LOGGER.error("Aop failure",e); } } private static Set<Class<?>> createTargetClassSet(Aspect aspect) throws Exception { Set<Class<?>> targetClassSet = new HashSet<Class<?>>(); 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>>(); for (Map.Entry<Class<?>, Set<Class<?>>> proxyEntry : proxyMap.entrySet()) { Class<?> proxyClass = proxyEntry.getKey(); Set<Class<?>> targetClassSet = proxyEntry.getValue(); for (Class<?> targetClass : targetClassSet) { Proxy proxy = (Proxy) proxyClass.newInstance(); if (targetMap.containsKey(targetClass)) { targetMap.get(targetClass).add(proxy); } else { List<Proxy> proxyList = new ArrayList<Proxy>(); proxyList.add(proxy); targetMap.put(targetClass, proxyList); } } } return targetMap; } private static Map<Class<?>, Set<Class<?>>> createProxyMap() throws Exception { Map<Class<?>, Set<Class<?>>> proxyMap = new HashMap<Class<?>, Set<Class<?>>>(); 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; } }
修改BeanHelper
package com.lhx.smart.framework.helper; import com.lhx.smart.framework.util.ReflectionUtil; import java.util.HashMap; import java.util.Map; import java.util.Set; public final class BeanHelper { /** * 定义bena映射(用于存放Bean类与Bean实例的映射关系) */ private static final Map<Class<?>, Object> BEAN_MAP = new HashMap<Class<?>, Object>(); static { Set<Class<?>> beanClassSet = ClassHelper.getBeanClassSet(); for (Class<?> beanClass : beanClassSet) { Object obj = ReflectionUtil.newInstance(beanClass); BEAN_MAP.put(beanClass, obj); } } public static void setBean(Class<?> cls,Object obj){ BEAN_MAP.put(cls,obj); } public static Map<Class<?>, Object> getBeanMap() { return BEAN_MAP; } public static <T> T getBean(Class<T> cls) { if (!BEAN_MAP.containsKey(cls)) { throw new RuntimeException("没有此bean的实例" + cls); } return (T) BEAN_MAP.get(cls); } }
修改Classhelper
package com.lhx.smart.framework.helper; import com.lhx.smart.framework.annotation.Controller; import com.lhx.smart.framework.annotation.Service; import com.lhx.smart.framework.util.ClassUtil; import java.lang.annotation.Annotation; import java.util.HashSet; import java.util.Set; /** * 类操作助手类 */ public class ClassHelper { /** * 定义类集合(用于存放所加载的类) */ private static final Set<Class<?>> CLASS_SET; static { String basePackage = ConfigHelper.getAppBasePackage(); CLASS_SET = ClassUtil.getClassSet(basePackage); } /** * 获取应用报名下的所有类 * * @return */ public static Set<Class<?>> getClassSet() { return CLASS_SET; } /** * 获取包应用名下所有Service类 */ public static Set<Class<?>> getServiceClassSet() { Set<Class<?>> classSet=new HashSet<Class<?>>(); for (Class<?> cls : CLASS_SET) { if(cls.isAnnotationPresent(Service.class)){ classSet.add(cls); } } return classSet; } /** * 获取包应用名下所有Controller类 */ public static Set<Class<?>> getControllerClassSet() { Set<Class<?>> classSet=new HashSet<Class<?>>(); for (Class<?> cls : CLASS_SET) { if(cls.isAnnotationPresent(Controller.class)){ classSet.add(cls); } } return classSet; } /** * 获取包应用名下所有Bean类 */ public static Set<Class<?>> getBeanClassSet() { Set<Class<?>> beanClassSet=new HashSet<Class<?>>(); beanClassSet.addAll(getServiceClassSet()); beanClassSet.addAll(getControllerClassSet()); return beanClassSet; } /** * 获取应用包名下某父类(或接口)的所有子类(或实现类) * @param superClass * @return */ public static Set<Class<?>> getClassSetBySuper(Class<?> superClass){ Set<Class<?>> classSet = new HashSet<Class<?>>(); for (Class<?> cls : CLASS_SET) { if(superClass.isAssignableFrom(cls)&&!superClass.equals(cls)){ classSet.add(cls); } } return classSet; } /** * 获取应用包名下带有某注解的所有类 * @param annotationClass * @return */ public static Set<Class<?>> getClassSetByAnnotation(Class<? extends Annotation> annotationClass){ Set<Class<?>> classSet = new HashSet<Class<?>>(); for (Class<?> cls : CLASS_SET) { if(cls.isAnnotationPresent(annotationClass)){ classSet.add(cls); } } return classSet; } }
在HelperLoader增加启动
package com.lhx.smart.framework; import com.lhx.smart.framework.helper.*; import com.lhx.smart.framework.util.ClassUtil; public final class HelperLoader { public static void init() { Class<?>[] classList = { ClassHelper.class, BeanHelper.class, AopHelper.class, IocHelper.class, ControllerHelper.class }; for (Class<?> cls : classList) { ClassUtil.loadClass(cls.getName(),true); } } }
测试待后续