内容只是个人的理解, 没有看源码, 会与实际情况有差异。有源码分析的同志, 万分感谢能够指点我以下。
@Resource 标签 name 属性的使用
在sping中, 被@Component标签标识的类会在servlet容器启动时加载单实例(默认设置下), @Resource标签负责注入。
如果@Resource标签的类型没有被提前加载, 则会报错。
在装载过程中, 会根据类名(不包括package地址)判断, 出现重复的类名会报异常(不在同一个package, 也会报异常)。所以同一个接口的多个实现类, 能够被正常加载。
在匹配过程中@Resource标签默认会根据name属性的值判断( @Resource(name="自定义的名称") ),
@Resource(name = "arg1") |
定义了name属性的值, 就只按照name值匹配 |
@Resource | 根据属性名匹配, 如果匹配不到就进行type匹配 |
对于接口, 会去寻找其实现类进行匹配, 所以需要注意有多个实现类的时候, 会匹配出多个结果, 如果不指定name值, 会报异常
下面是测试代码,根据代码会比较直观一点。
1 package com.springmvc.bean; 2 3 import org.springframework.stereotype.Component; 4 5 @Component("arg1") 6 public class AunotationBean { 7 8 public AunotationBean() { 9 System.out.println("constructors of com.springmvc.[bean].AunotationBean"); 10 } 11 12 public void init() { 13 System.out.println("init com.springmvc.[bean].AunotationBean"); 14 } 15 }
1 package com.springmvc.bean; 2 3 public interface Temporary { 4 5 void init(); 6 }
1 package com.springmvc.bean; 2 3 import org.springframework.stereotype.Component; 4 5 @Component("temp1") 6 public class Temporary1Impl implements Temporary { 7 8 public Temporary1Impl() { 9 System.out.println("constructors of Temporary[1]Impl"); 10 } 11 12 @Override 13 public void init() { 14 System.out.println("init Temporary[1]Impl"); 15 } 16 }
1 package com.springmvc.bean; 2 3 import org.springframework.stereotype.Component; 4 5 @Component("temp2") 6 public class Temporary2Impl implements Temporary { 7 8 public Temporary2Impl() { 9 System.out.println("constructors of Temporary[2]Impl"); 10 } 11 12 @Override 13 public void init() { 14 15 System.out.println("init Temporary[2]Impl"); 16 } 17 }
1 package com.springmvc.demo; 2 3 import org.springframework.stereotype.Component; 4 5 @Component("arg2") 6 public class AunotationBean { 7 8 public AunotationBean() { 9 System.out.println("constructors of com.springmvc.[demo].AunotationBean"); 10 } 11 12 public void init() { 13 System.out.println("init com.springmvc.[demo].AunotationBean"); 14 } 15 }
1 package com.springmvc.main; 2 3 import javax.annotation.Resource; 4 5 import org.springframework.stereotype.Component; 6 7 import com.springmvc.bean.Temporary; 8 9 @Component 10 public class SpringmvcTest { 11 12 @Resource(name = "arg1") 13 com.springmvc.bean.AunotationBean arg1; // 定义了name属性的值, 就只按照name值匹配 14 15 @Resource 16 com.springmvc.demo.AunotationBean arg2; // 根据属性(arg2)匹配, 如果匹配不到就进行type匹配 17 18 @Resource // 接口会去寻找其实现类 19 Temporary temp1; // 如果此处是 Temporary temp11, 会先根据temp11寻找, 找不到的时候再根据Temporary寻找, 会寻找到2个实现类 20 21 @Resource // 如果不定义name, 那么会自动根据name(temp2)属性值进行匹配 22 Temporary temp2; 23 24 // [个人猜测]装载的时候是根据类名是否重复进行判断, 同一个接口的多个实现类只要类名不同即可通过编译, 但是没有直接关联的两个类如果类名相同, 不会通过编译, 匹配的时候如果是接口类型, 那么会寻找其实现类, 这个时候会出现有多个选择的问题 25 }
1 package com.springmvc.main; 2 3 import org.springframework.beans.factory.annotation.Autowired; 4 import org.springframework.stereotype.Component; 5 6 @Component 7 public class SpringmvcMain { 8 9 public SpringmvcMain(@Autowired SpringmvcTest args) { 10 args.arg1.init(); 11 args.arg2.init(); 12 args.temp1.init(); 13 args.temp2.init(); 14 } 15 }
时间: 2024-10-22 07:26:25