一塊兒寫框架-Ioc內核容器的實現-基礎功能-組件註解支持自定義的對象名(九)

實現功能

若是掃描組件註解(@Controller,@Service,@Repository,@Component)默認對象名,已經實現了默認使用首字母小寫類名的做爲對象名。測試

但,現實需求中。咱們有時候但願能夠本身定義對象的名。this

實現思路

1.得到掃描組件註解的name屬性的值。spa

2.將這個值做爲對象名code

實現步驟

1.AbstractApplicationContext增長一個方法getComponentOfName,用於判斷組件註解是否設置了name屬性。若是設置了就得到該值component

 

 1 /**
 2      * 得到組件的對象名
 3      * 
 4      * @param classType
 5      * @return
 6      */
 7     private String getComponentOfName(Class<?> classType) {
 8         //得到四個組件註解的對象
 9         Component component = classType.getDeclaredAnnotation(Component.class);
10         Service service = classType.getDeclaredAnnotation(Service.class);
11         Controller controller = classType.getDeclaredAnnotation(Controller.class);
12         Repository repository = classType.getDeclaredAnnotation(Repository.class);
13         //判斷註解對象是否爲空,註解對象的的name屬性是否有值
14         if (component != null) {
15             if (!"".equals(component.name()) && component.name() != null) {
16                 return component.name();
17             }
18         } 
19         if (service != null) {
20             if (!"".equals(service.name()) && service.name() != null) {
21                 return service.name();
22             }
23         } 
24         if (controller != null) {
25             if (!"".equals(controller.name()) && controller.name() != null) {
26                 return controller.name();
27             }
28         } 
29         if (repository != null) {
30             if (!"".equals(repository.name()) && repository.name() != null) {
31                 return repository.name();
32             }
33         }
34         return null;
35 
36     }

 

2.修改AbstractApplicationContext類的構造方法。標紅處對象

 

 1 /**
 2      * 將容器操做加載建立對象的代碼寫抽象類裏面,這樣能夠方便之後擴展多種實現。
 3      * 
 4      * @param classType
 5      */
 6     public AbstractApplicationContext(Class<?> classType) {
 7         // 判斷配置類是否有Configuration註解
 8         Configuration annotation = classType.getDeclaredAnnotation(Configuration.class);
 9         if (annotation != null) {
10             // 得到組件掃描註解
11             ComponentScan componentScan = classType.getDeclaredAnnotation(ComponentScan.class);
12             // 得到包名
13             this.basePackage = componentScan.basePackages();
14             // 根據包名得到類全限制名
15             // Set<String> classNames =
16             // PackageUtils.getClassName(this.basePackage[0], true);
17             // 將掃描一個包,修改成多個包
18             Set<String> classNames = PackageUtils.getClassNames(this.basePackage, true);
19             // 經過類名建立對象
20             Iterator<String> iteratorClassName = classNames.iterator();
21             while (iteratorClassName.hasNext()) {
22 
23                 String className = iteratorClassName.next();
24                 // System.out.println(className);
25                 try {
26                     // 經過類全名建立對象
27                     Class<?> objectClassType = Class.forName(className);
28                     /*
29                      * 判斷若是類權限名對應的不是接口,而且包含有@Component|@Controller|@Service|
30                      * @Repository 才能夠建立對象
31                      */
32                     if (this.isComponent(objectClassType)) {
33                         Object instance = objectClassType.newInstance();
34                         // 修改成,默認對象支持首字符小寫
35                         String objectName=null;
36                         //得到組件註解的name屬性值
37                         String componentName = this.getComponentOfName(objectClassType);
38                     
39                         if(componentName==null){
40                             //若是組件註解的name屬性沒有值,使用默認命名對象
41                             objectName= NamingUtils.firstCharToLower(instance.getClass().getSimpleName());
42                         }else{
43                             //若是組件註解的name屬性有值,使用自定義命名對象
44                             objectName=componentName;
45                         }
46                         this.getContext().addObject(objectName, instance);
47                     }
48                 } catch (InstantiationException e) {
49                     e.printStackTrace();
50                 } catch (IllegalAccessException e) {
51                     e.printStackTrace();
52                 } catch (ClassNotFoundException e) {
53                     e.printStackTrace();
54                 }
55             }
56         }
57     }

 

測試代碼

1.修改UserService類的組件註解blog

 

 1 package ioc.core.test.service;
 2 
 3 import ioc.core.annotation.stereotype.Service;
 4 
 5 /**
 6  * 一個普通的類,用於測試是否能夠建立對象
 7  * @author ranger
 8  *
 9  */
10 @Service(name="uService")
11 public class UserService {
12     
13     public void login(){
14         System.out.println("-登陸Service-");
15     }
16 
17 }

 

2.測試類接口

 1 package ioc.core.test;
 2 
 3 import org.junit.Test;
 4 
 5 import ioc.core.impl.AnntationApplicationContext;
 6 import ioc.core.test.config.Config;
 7 import ioc.core.test.service.UserService;
 8 
 9 public class AnntationApplicationContextTest {
10     
11     @Test
12     public void login(){
13         try {
14             AnntationApplicationContext context=new AnntationApplicationContext(Config.class);
15             UserService userService = context.getBean("uService", UserService.class);
16             userService.login();
17             System.out.println(context.getContext().getObjects());
18         
19         } catch (Exception e) {
20             e.printStackTrace();
21         }
22     }
23 
24 }

3.測試結果get

相關文章
相關標籤/搜索