一、代码地址

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);
}
}
}

测试待后续

007-搭建框架-开发AOP框架的更多相关文章

  1. .Net常见的IOC框架及AOP框架

    IOC框架 Unity:微软patterns&practicest团队开发的IOC依赖注入框架,支持AOP横切关注点. MEF(Managed Extensibility Framework) ...

  2. 简单搭建iOS开发项目框架

    今天我们来谈谈如何搭建框架,框架需要做一些什么. 第一步:找到我们的目标我们的目标是让其他开发人员拿到手后即可写页面,不再需要考虑其他的问题. 第二步:我们需要做哪些东西各位跟着我一步一步来进行. 假 ...

  3. 使用EasySYS搭建驱动开发基本框架

    提供EasySYS的下载地址:http://bbs.pediy.com/showthread.php?p=956643,看雪上有提供下载,自行百度. EasySYS你能够帮我们快速的搭建驱动的开发框架 ...

  4. mui框架开发aop的跨页面传值

    mui开发跨平台app,其实不乏会涉及到跨页面传值,今天给大家简单介绍一种常用也是简单的传值方法 咱在这里设置一个场景,就是两个页面进入到同一页面展示不同的元素,此时需要在这两个页面各自设置一个区别的 ...

  5. 架构探险笔记5-使框架具备AOP特性(下)

    开发AOP框架 借鉴SpringAOP的风格,写一个基于切面注解的AOP框架.在进行下面的步骤之前,确保已经掌了动态代理技术. 定义切面注解 /** * 切面注解 */ @Target(Element ...

  6. [Spring框架]Spring AOP基础入门总结二:Spring基于AspectJ的AOP的开发.

    前言: 在上一篇中: [Spring框架]Spring AOP基础入门总结一. 中 我们已经知道了一个Spring AOP程序是如何开发的, 在这里呢我们将基于AspectJ来进行AOP 的总结和学习 ...

  7. MUI框架开发HTML5手机APP(一)--搭建第一个手机APP

      前  言 JRedu 随着HTML5的不断发展,移动开发成为主流趋势!越来越多的公司开始选择使用HTML5开发手机APP,而随着手机硬件设备配置的不断提升,各种开发框架的不断优化,也使着H5开发的 ...

  8. SSM框架开发web项目系列(一) 环境搭建篇

    前言 开发环境:Eclipse Mars + Maven + JDK 1.7 + Tomcat 7 + MySQL 主要框架:Spring + Spring MVC + Mybatis 目的:快速上手 ...

  9. MUI框架开发HTML5手机APP(一)--搭建第一个手机APP(转)

    出处:http://www.cnblogs.com/jerehedu/p/7832808.html  前  言 JRedu 随着HTML5的不断发展,移动开发成为主流趋势!越来越多的公司开始选择使用H ...

随机推荐

  1. Android 使用handler实现线程间发送消息 (主线程 与 子线程之间)、(子线程 与 子线程之间)

    keyword:Android 使用handler实现线程间发送消息 (主线程 与 子线程之间).(子线程 与 子线程之间) 相信大家平时都有使用到异步线程往主线程(UI线程)发送消息的情况. 本文主 ...

  2. 内核并发管理---spin lock

    自旋锁最初是为了在smp系统上使用而设计. 1.在单处理器非抢占模式下,自旋锁不做任何事情. #ifdef CONFIG_PREEMPT_COUNT     //支持抢占模式 #define pree ...

  3. 没有局域网环境,全是公网IP可以做LVS吗,该如何做了!请大家赐教!

    没有局域网环境,全是公网IP可以做LVS吗,该如何做了!请大家赐教! 由 wjjava 在 周四, -- : 提交 LVS集群 现在有3台服务器,各有一个公网IP地址.IP地址形式如下: IP1:12 ...

  4. iOSXib布局后代码修改约束的值

      如何修改autolayout 约束的值? 目前我已知的方法有5种 1.修改frame(有时候可能会不起作用,但可以做动画) 2.修改约束的float值 3.使用VisualFormat 语言 4. ...

  5. mount rootfs

    主要用到的命令为pivot_root,可man 8 pivot_root了解用法. 1. pivot_root - change the root filesystem pivot_root new_ ...

  6. 如何让git小乌龟工具TortoiseGit记住你的账号密码

    在使用小乌龟的过程中,发下每次push或者pull都要重复输入账号密码,非常麻烦. 如果能记住账号密码就好了,这样就省去了时间. 怎么设置记住密码 在[系统盘]:\Users[你的用户名]下面,有一个 ...

  7. linux虚拟文件系统vfs

    linux可以挂载不同的文件系统(EXT2,FAT,NTFS),用同一的样式呈现给用户,读写操作用起来都一样,这是怎样做到的呢? linux内核在各种不同的文件系统格式上做了一个抽象层,使得文件.目录 ...

  8. Appium python自动化测试系列之元素的定位(六)

    ​6.1 常用定位方法讲解 对象定位是自动化测试中很关键的一步,也可以说是最关键的一步,毕竟你对象都没定位那么你想操作也不行.所以本章节的知识我希望大家多动手去操作,不要仅仅只是书本上的知识,毕竟这个 ...

  9. 把world转成html

    本来用php转的 效果不太理想 很不稳定 最后试了下java 效果不错 只记录java的方法好了 其实他们的原理都是一样的啊,都是用到了微软的com 首先是准备工作 下载(明确dll的版本是64位的还 ...

  10. php基本语法之逻辑运算符

    百度经验 | 百度知道 | 百度首页 | 登录 | 注册 新闻 网页 贴吧 知道 经验 音乐 图片 视频 地图 百科 文库 帮助 首页 分类 杂志 任务 签到 回享计划 商城 知道 百度经验 > ...