Spring容器解析与简单demo

git上项目路径: https://github.com/0ziyu0/handWriting

实现原理:本文采用2个全局的ConcurrentHashMap集合来实现beansAlias集合存放所有带自定义注解的类其中key:类名首字母小写,value:注解中value属性,没有则首字母小写。

                  containerBeans集合存放所有自定义注解的类来实现。

步骤: 1.扫描指定路径下的所有class文件。

         2.对其上有自定义注解的class放入一个全局的Map集合中,同时用一个容器来存放beanId(默认是类名首字母小写)[也可以更具类的类型来注入]。

         3.遍历所有Map集合对其class中属性上有自定义注解进行赋值(依赖注入)。

 

  1 public class ClassPathApplicationContextCustomer {
  2 
  3     // 扫描包路径
  4     private String scanPackagePath = null;
  5     // 将所有自定义注解的class交给此类管理
  6     private ConcurrentHashMap<String, Object> containerBeans = new  ConcurrentHashMap<String, Object>();
  7     // 存放注解中bean的别名
  8     private ConcurrentHashMap<String, String> beansAlias = new ConcurrentHashMap<String, String>();
  9     
 10     public ClassPathApplicationContextCustomer(String scanPackagePath) {
 11         this.scanPackagePath = scanPackagePath;
 12         List<Class> annotationClassList = getAllAnnotationClass();
 13         initAnnotationBean(annotationClassList);
 14         for (Object classInfo : containerBeans.values()) { 
 15             attributeInjection(classInfo);
 16         }
 17         beansAlias = null;
 18     }
 19     
 20     // 得到包路径下所有的注解类
 21     private List<Class> getAllAnnotationClass() {
 22 
 23         List<Class> resultAllAnnotationClass = null;
 24         if(StringUtil.isNotEmpty(scanPackagePath)) {
 25             resultAllAnnotationClass = new ArrayList<Class>();
 26             String beanId = null;
 27             String className = null;
 28             // 获取包下所有类
 29             List<Class<?>> classeList = ClassUtil.getClasses(scanPackagePath);
 30             for (Class<?> classInfo : classeList) {
 31                 CustomerService customerServiceAnnotation = classInfo.getDeclaredAnnotation(CustomerService.class);
 32                 if(customerServiceAnnotation != null) {
 33                     resultAllAnnotationClass.add(classInfo);
 34                     // 是否有自定义bean的名字,没有则采用类名小写
 35                     beanId = customerServiceAnnotation.value();
 36                     // 防止类重名,最好不用SimpleName()方法,这里简单处理
 37                     className = classInfo.getSimpleName();
 38                     if(StringUtil.isEmpty(beanId)) {
 39                         beanId = StringUtil.toLowerCaseFirstOne(className);
 40                     }
 41                     beansAlias.put(className, beanId);
 42                 }
 43             }
 44         }
 45 
 46         return resultAllAnnotationClass;
 47     }
 48 
 49     // 初始化bean容器[此方法也可以合并到getAllAnnotationClass()方法中]
 50     private void initAnnotationBean(List<Class> AnnotationClassList) {
 51 
 52         try {
 53             Object instance = null;
 54             String className = null;
 55             for (Class classInfo : AnnotationClassList) {
 56                 instance = classInfo.newInstance();
 57                 className = classInfo.getSimpleName();
 58                 String beanId = beansAlias.get(className);
 59                 containerBeans.put(beanId, instance);
 60             }
 61         } catch (Exception e) {
 62             e.printStackTrace();
 63             throw new RuntimeException(e);
 64         }
 65 
 66     }
 67 
 68     // 属性的依赖注入
 69     private void attributeInjection(Object object) {
 70 
 71         try {
 72             Class<? extends Object> classInfo = object.getClass();
 73             Field[] fieldArray = classInfo.getDeclaredFields();
 74             CustomerService customerServiceAnnotation = null;
 75             String filedName = null;
 76             Object injectionClass = null;
 77             for (Field field : fieldArray) {
 78                 customerServiceAnnotation = field.getDeclaredAnnotation(CustomerService.class);
 79                 if(customerServiceAnnotation != null) {
 80                     filedName = field.getName();
 81                     injectionClass = containerBeans.get(filedName);
 82                     if(injectionClass != null) {
 83                         field.setAccessible(true);
 84                         field.set(object, injectionClass);
 85                     }
 86                 }
 87             }
 88         } catch (Exception e) {
 89             e.printStackTrace();
 90             throw new RuntimeException(e);
 91         }
 92     }
 93     
 94     public Object getInstanceBean(String beanId) {
 95         
 96         Object resultObject = null;
 97         if(StringUtil.isNotEmpty(beanId)) {
 98             resultObject = containerBeans.get(beanId);
 99         }
100         
101         return resultObject;
102         
103     }
104 }
@Documented
@Target({ElementType.TYPE, ElementType.FIELD})
@Inherited
@Retention(RetentionPolicy.RUNTIME )
public @interface CustomerService {

    String value() default "";
//    String name() default "";
    
}

 测试代码

dao

1 package com.hand.customer.spring.dao;
2 
3 public interface CustomerApplicationContextDao {
4 
5     public void testCustomerApplicationContextTest();
6     
7 }

dao.impl

 1 package com.hand.customer.spring.dao.impl;
 2 
 3 import com.hand.customer.spring.annotation.CustomerService;
 4 import com.hand.customer.spring.dao.CustomerApplicationContextDao;
 5 
 6 @CustomerService("customerDao")
 7 public class CustomerApplicationContextDaoImpl implements CustomerApplicationContextDao {
 8 
 9     public void testCustomerApplicationContextTest() {
10         
11         System.out.println("this is test customer application content test dao impl...");
12         
13     }
14 
15 }

service

1 package com.hand.customer.spring.service;
2 
3 public interface CustomerApplicationContextService {
4 
5     public void testCustomerApplicationContextTest();
6     
7 }

service.impl

 1 package com.hand.customer.spring.service.impl;
 2 
 3 import com.hand.customer.spring.annotation.CustomerService;
 4 import com.hand.customer.spring.dao.CustomerApplicationContextDao;
 5 import com.hand.customer.spring.service.CustomerApplicationContextService;
 6 
 7 @CustomerService()
 8 public class CustomerApplicationContextServiceImpl implements CustomerApplicationContextService {
 9     
10     @CustomerService("customerDao")
11     private CustomerApplicationContextDao customerDao;
12     
13     public void testCustomerApplicationContextTest() {
14         
15         System.out.println("============== 注解版本(根据bean首字母小写注入) ==================");
16         customerDao.testCustomerApplicationContextTest();
17     }
18 
19 }

Test方法

 1 package com.hand.customer.spring;
 2 
 3 import com.hand.customer.spring.service.CustomerApplicationContextService;
 4 
 5 public class ClassPathApplicationContextCustomerTest {
 6 
 7     public static void main(String[] args) {
 8         
 9         ClassPathApplicationContextCustomer app = new ClassPathApplicationContextCustomer("com.hand.customer.spring");
10         CustomerApplicationContextService customerService = (CustomerApplicationContextService) app.getInstanceBean("customerApplicationContextServiceImpl");
11         customerService.testCustomerApplicationContextTest();
12     }
13     
14 }

运行测试

 

posted @ 2019-01-07 14:24  东隅已逝x  Views(159)  Comments(0)    收藏  举报