动态链接做网站外链图南京网站制作公司招聘
动态链接做网站外链图,南京网站制作公司招聘,建筑人才网邀约投递,文秘写作网站实现功能 需求#xff1a;在类的成员属性使用Autowirde注解注入容器中的对象。 实现思路 要实现这个功能。我们首先要思考一个问题#xff1a;类与类的关系是在调用的建立的#xff0c;还是说在创建对象的时候就就将建立了#xff1f; ---我实现的方案是#xff0c;在在程…实现功能 需求在类的成员属性使用Autowirde注解注入容器中的对象。 实现思路 要实现这个功能。我们首先要思考一个问题类与类的关系是在调用的建立的还是说在创建对象的时候就就将建立了 ---我实现的方案是在在程序启动后所有对象创建后直接就将对象的属性和属性之间的关系创建了。接下来我就用这个思路来实现将根据Autowirde建立对象与对象之间的关系。 为什么一定要对象全部创建后再实现对象与对象直接的关系呢 这个是逻辑问题如果对象没有创建完就建立对象与对象之间的关系人家都还没有创建你怎么引用呢对吧。所有一定在所有对象创建完后建立对象与对象的关系。 实现步骤 1.Context接口增加一个方法。用于通过Map的和属性名对象或者对象的类型与属性的类型对象给属性匹配对象。定义如代码的说明 1 /**
2 * 根据类的类型以及设置的对象名返回容器对象
3 * 如果传入的类型容器中有对应key的对象而且返回类型是兼容的直接返回对应的对象。
4 * 如果传入的类型容器中有没有对应key的对象那么判断传入的类型是否和容器的对象的找到唯一配置的。
5 * 如果传入类型唯一匹配返回对象。如果没有或者配配多个对象都报一个RuntimeException异常
6 * param classType
7 * return
8 */
9 Object getObject(Class? classType,String key); 2.在ContextImpl容器实现类实现这个方法 1 Override2 public Object getObject(Class? classType, String key) {3 // 1.判断是否有对应key的对象4 Object object objects.get(key);5 // 2.如果有而且类型也兼容。直接返回该对象。6 if (object ! null classType.isAssignableFrom(object.getClass())) {7 return object;8 } else {9 // 3.如果没有对应key的对象那么就在容器里检索是否有兼容类型的对象。
10 CollectionObject values objects.values();
11 IteratorObject iterator values.iterator();
12 int count 0;
13 Object currentObject null;
14 while (iterator.hasNext()) {
15 Object nextObject iterator.next();
16 //判断classType是否是nextObject.getClass()的兼容类型。
17 boolean from classType.isAssignableFrom(nextObject.getClass()) ;
18 if (from) {
19 //如果发现有对象计数加1
20 count;
21 //并将对象赋予当前对象
22 currentObject nextObject;
23 }
24 }
25 // 如果兼容类型的对象只有一个返回这个对象。如果大于一个返回null
26 if (count 1) {
27 return currentObject;
28 } else {
29 //如果发现一个类型容器中有多个异常抛异常
30 throw new RuntimeException(容器中找不到对应的对象或者找到的对象不是唯一的请确认是否一个接口继承了多个类);
31 }
32
33 }
34
35 } 3.在AbstractApplicationContext容器操作类实现属性的注入方法 autowired() 1 /**2 * 给对象的属性注入关联的对象3 * throws IllegalArgumentException4 * throws IllegalAccessException5 */6 private void autowired() throws IllegalArgumentException, IllegalAccessException {7 // 1.获得容器8 Context context contexts.get();9 // 2.获得容器中的所有对象。
10 MapString, Object objects context.getObjects();
11 // 3.获得容器中所有的对象值
12 CollectionObject values objects.values();
13 // 4.获得对象的迭代器
14 IteratorObject iterator values.iterator();
15 while (iterator.hasNext()) {
16 Object object iterator.next();
17 // 5.获得对象的表结构
18 Class? extends Object classType object.getClass();
19 // 6.获得字段的结构
20 Field[] fields classType.getDeclaredFields();
21 for (int i 0; i fields.length; i) {
22 // autowired获得注解
23 Autowired autowired fields[i].getAnnotation(Autowired.class);
24 if (autowired ! null) {
25 Class? fieldType fields[i].getType();
26 String fieldName fields[i].getName();
27 // 如果容器里面有对应的对象
28 Object fieldObject context.getObject(fieldType, fieldName);
29 // 允许访问私有方法
30 if (fieldObject ! null) {
31 // 属性是私有的也可以访问
32 fields[i].setAccessible(true);
33 // 将属性值赋予这个对象的属性
34 fields[i].set(object, fieldObject);
35 }
36
37 }
38 }
39 }
40 } 4. 在AbstractApplicationContext构造方法最后调用属性注入方法autowired注意标红处 1 public AbstractApplicationContext(Class? classType) {2 try {3 // 判断配置类是否有Configuration注解4 Configuration annotation classType.getDeclaredAnnotation(Configuration.class);5 if (annotation ! null) {6 // 获得组件扫描注解7 ComponentScan componentScan classType.getDeclaredAnnotation(ComponentScan.class);8 // 获得包名9 this.basePackage componentScan.basePackages();
10 // 根据包名获得类全限制名
11 // SetString classNames
12 // PackageUtils.getClassName(this.basePackage[0], true);
13 // 将扫描一个包修改为多个包
14 SetString classNames PackageUtils.getClassNames(this.basePackage, true);
15 // 通过类名创建对象
16 IteratorString iteratorClassName classNames.iterator();
17 while (iteratorClassName.hasNext()) {
18
19 String className iteratorClassName.next();
20 // System.out.println(className);
21
22 // 通过类全名创建对象
23 Class? objectClassType Class.forName(className);
24 /*
25 * 判断如果类权限名对应的不是接口并且包含有Component|Controller|Service|
26 *
27 * Repository 才可以创建对象
28 */
29 if (this.isComponent(objectClassType)) {
30 Object instance objectClassType.newInstance();
31 // 修改为,默认对象支持首字符小写
32 String objectName null;
33 // 获得组件注解的name属性值
34 String componentName this.getComponentOfName(objectClassType);
35
36 if (componentName null) {
37 // 如果组件注解的name属性没有值使用默认命名对象
38 objectName NamingUtils.firstCharToLower(instance.getClass().getSimpleName());
39 } else {
40 // 如果组件注解的name属性有值使用自定义命名对象
41 objectName componentName;
42 }
43 this.getContext().addObject(objectName, instance);
44 }
45
46 }
47 }
48 //1.注入对象到属性中。
49 autowired();
50 } catch (InstantiationException e) {
51 e.printStackTrace();
52 } catch (IllegalAccessException e) {
53 e.printStackTrace();
54 } catch (ClassNotFoundException e) {
55 e.printStackTrace();
56 }
57
58 } 测试代码 测试类目录结构 1.修改UserController代码增加注入UserService的代码 1 package ioc.core.test.controller;2 3 import ioc.core.annotation.Autowired;4 import ioc.core.annotation.stereotype.Controller;5 import ioc.core.test.service.UserService;6 7 Controller8 public class UserController {9
10 /**
11 * 通过Autowired可以注入UserService的对象。
12 */
13 Autowired
14 private UserService userServiceImpl;
15
16 public void login(){
17 System.out.println(-登录Controller-);
18 userServiceImpl.login();
19 }
20
21 } 2.调用UserController 对象 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.controller.UserController;8 9 public class AnntationApplicationContextTest {
10
11 Test
12 public void login(){
13 try {
14 AnntationApplicationContext contextnew AnntationApplicationContext(Config.class);
15 UserController userController context.getBean(userController, UserController.class);
16 userController.login();
17 System.out.println(context.getContext().getObjects());
18
19 } catch (Exception e) {
20 e.printStackTrace();
21 }
22 }
23
24 } 3.输出结果 同时输出了UserController的内容和UserService的内容 转载于:https://www.cnblogs.com/zhuyuejiu/p/7819694.html
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/89097.shtml
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!