以注解方式模拟Spring的IoC,AOP
2015-09-10 13:10
447 查看
目录结构:
@Component注解代码:
@Resource代码:
Ioc实现代码:
AOP实现代码:
studentDAOImp和teacherDAOImp都带有@Component注解,比较简单.这里只给出studentServiceImp的代码:
MyTest测试代码:
输出结果:
Before: Class Name:StudentServiceImp method name:save
StudentDAOImp save
TeacherDAOImp save
After : Class Name:StudentServiceImp method name:save
写了这个例子,对Spring的理解又更深了一步.
源码下载:
CSDN:http://download.csdn.net/detail/lc0817/9100991
SVN repository:http://code.taobao.org/svn/Spring_Simulation/
@Component注解代码:
package glut.annotation; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; @Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) public @interface Component { String value() default ""; }
@Resource代码:
package glut.annotation; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; @Target(ElementType.FIELD) @Retention(RetentionPolicy.RUNTIME) public @interface Resource { String value();// 默认要给出需要注入的实例名 }
Ioc实现代码:
package glut.spring; import glut.annotation.Component; import glut.annotation.Resource; import java.io.File; import java.lang.reflect.Field; import java.util.Collection; import java.util.HashMap; import java.util.Map; public class BeanFactory { /** * pkg:package to scan; */ private String pkg; /** * 将Component注解的value返回值作为key,对应的类作为value,存放在instanceMap中 */ private Map<String, Object> instanceMap = new HashMap<>(); /** * 如果使用无参构造器,之后请记得使用setPkg方法 */ public BeanFactory() { // TODO Auto-generated constructor stub } /** * 调用该构造器会回调ioc * * @param pkg */ public BeanFactory(String pkg) { this.pkg = pkg; IoC(); } private void IoC() { // 将包形式转换为文件路径形式 String pkgPath = pkg.replaceAll("\\.", "/"); // 获取当前project的绝对路径 String projectPath = BeanFactory.class.getResource("/").toString(); // 对获取的路径进行处理,去掉开头的file:/ projectPath = projectPath.substring(projectPath.indexOf("/") + 1); // 获取指定路径下的所有文件 // 遍历所有的文件和文件夹 recursion(new File(projectPath + pkgPath)); findResource(); } // 将instanceMap里所有的实例的filed找出,看看是否存在@Resource,如果存在就将它实例化 private void findResource() { // TODO Auto-generated method stub // 获取指定路径pkg下存在@Component的所有对象实例 Collection<Object> values = instanceMap.values(); for (Object obj : values) { try { initResource(obj); } catch (IllegalArgumentException | IllegalAccessException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } /** * 初始化带有@Resource的field * * @param obj * field的拥有者 * @throws IllegalArgumentException * @throws IllegalAccessException */ private void initResource(Object obj) throws IllegalArgumentException, IllegalAccessException { // TODO Auto-generated method stub Class<? extends Object> clz = obj.getClass(); Field[] fields = clz.getDeclaredFields(); for (Field f : fields) { Class<Resource> res = Resource.class; if (f.isAnnotationPresent(res)) { Resource r = f.getAnnotation(res); String resName = r.value(); Object o = instanceMap.get(resName); f.setAccessible(true); f.set(obj, o); } } } /** * 递归寻找指定路径下的所有类文件 * * @param file */ private void recursion(File file) { File[] files = file.listFiles(); for (File f : files) { if (f.isFile()) { fillMap(f); } else { recursion(f); } } } /** * 对找到类文件进行处理,将该类文件头上的注解解析,将对应信息存放到map中 * * @param f */ private void fillMap(File f) { // 类的绝对路径 String absolutePath = f.getAbsolutePath(); // 包路径 String pkgPath = absolutePath.replaceAll("\\\\", "."); // 获取类路径,并去掉文件格式 String objPath = pkgPath.substring(pkgPath.indexOf(pkg), pkgPath.length() - 6); try { // 通过类路径创建指定的类 Class<?> clz = Class.forName(objPath); Class<Component> annoClz = Component.class; Class<Resource> res = Resource.class; if (clz.isAnnotationPresent(annoClz)) { Component c = clz.getAnnotation(annoClz); Object instance = clz.newInstance(); String instanceName = ""; String annoValue = c.value(); // 如果使用的是默认值,则以类名为key存入map if ("".equals(annoValue)) { instanceName = instance.getClass().getSimpleName(); // 将类名第一个字母改成小写 instanceName = (instanceName.charAt(0) + "").toLowerCase() + instanceName.substring(1); } else { instanceName = annoValue; } // 存放到map中,如果返回值不为空,则表明已存在同名实例. if (instanceMap.put(instanceName, instance) != null) { throw new Exception("存在同名实例"); } } } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } } public Map<String, Object> getInstances() { return instanceMap; } /** * 根据实例名获取实例 * * @param instanceName * 实例名 * @return 实例 */ public <T> T getInstance(String instanceName) { return (T) instanceMap.get(instanceName); } public String getPkg() { return pkg; } /** * 调用set方法会回调IoC * * @param pkg */ public void setPkg(String pkg) { this.pkg = pkg; IoC(); } }
AOP实现代码:
package glut.spring; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; public class DynamicProxy implements InvocationHandler { private Object target; public DynamicProxy() { // TODO Auto-generated constructor stub } public DynamicProxy(Object target) { super(); this.target = target; } public static <T> T bind(Object obj) { Class<? extends Object> clz = obj.getClass(); return (T) Proxy.newProxyInstance(clz.getClassLoader(), clz.getInterfaces(), new DynamicProxy(obj)); } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { // TODO Auto-generated method stub before(proxy, method, args); Object invoke = method.invoke(target, args); after(proxy, method, args); return invoke; } private void before(Object proxy, Method method, Object[] args) { // TODO Auto-generated method stub System.out.println("Before:" + " Class Name:" + target.getClass().getSimpleName() + " method name:" + method.getName()); } private void after(Object proxy, Method method, Object[] args) { // TODO Auto-generated method stub System.out.println("After :" + " Class Name:" + target.getClass().getSimpleName() + " method name:" + method.getName()); } public Object getTarget() { return target; } public void setTarget(Object target) { this.target = target; } }
studentDAOImp和teacherDAOImp都带有@Component注解,比较简单.这里只给出studentServiceImp的代码:
package glut.service; import glut.annotation.Component; import glut.annotation.Resource; import glut.dao.IStudentDAO; import glut.dao.ITeacherDAO; @Component public class StudentServiceImp implements IStudentService { @Resource("studentDAOImp") private IStudentDAO sd; @Resource("teacherDAOImp") private ITeacherDAO td; @Override public void save() { // TODO Auto-generated method stub // 通过该servvice调用sd,td两个dao. sd.save(); td.save(); } }
MyTest测试代码:
package glut.test; import glut.service.IStudentService; import glut.spring.BeanFactory; import glut.spring.DynamicProxy; import org.junit.Test; public class MyTest { @Test public void test() { // pkgToScan:要扫描的包路径,多个同前缀的包会递归处理 String pkgToScan = "glut"; BeanFactory bf = new BeanFactory(pkgToScan); IStudentService iss = bf.getInstance("studentServiceImp"); // AOP绑定 iss = DynamicProxy.bind(iss); iss.save(); } }
输出结果:
Before: Class Name:StudentServiceImp method name:save
StudentDAOImp save
TeacherDAOImp save
After : Class Name:StudentServiceImp method name:save
写了这个例子,对Spring的理解又更深了一步.
源码下载:
CSDN:http://download.csdn.net/detail/lc0817/9100991
SVN repository:http://code.taobao.org/svn/Spring_Simulation/
相关文章推荐
- Spring资源抽象接口--Resource
- JAVA正则表达式 Pattern和Matcher
- quartz2.2.1与spring3.2.8版本不兼容的问题
- java bean 转为JSON
- solr4.7学习
- 如何把Java Script写成类
- 冒泡排序算法原理及JAVA实现
- java3
- 什么导致了Context泄露:Handler&内部类
- eclipse中查看storm0.9.3示例代码storm-start-05.docx
- SysLog简介和java操作实例
- Java实现图的遍历(深搜与广搜)
- java简单的输入语句(字符串)
- JAVA基础应用——POI操作Excel
- PWC6345: There is an error in invoking javac
- Spring MVC 总结一(spring mvc 基本例子)
- java-list去除重复的对象
- Eclipse JAVA文件注释乱码
- java 排序算法--冒泡排序
- MyEclipse使用汇总——MyEclipse10设备SVN插入