最近在做公司级的一个项目,大概就是关于把公司以前的一个人工上线流程重构一套类似审批流来完成,理论上节省了沟通成本,也为公司节省了成本。期间跟一个同事合作,字段的注入用的全是 @Autowired 代码更新下来,满屏的提示: Field injection is not recommended (字段注入是不被推荐的) 哎,看的我叫一个恶心呀。难道我有代码洁癖? 所以 今天 我就再来梳理一下 这个问题,希望 这位同事看到吧 哈哈哈哈。 问题一:@Resource @Autowired 都是按照什么方式来注入的? 依赖注入方式:@Autowired默认是 byType 可以使用@Qualifier指定Name,@Resource 默认ByName 如果 找不到则ByType 适用对象:@Autowired可以对 构造器、方法、参数、字段 使用,@Resource只能对 方法、字段 使用 提供方:@Autowired是 Spring 提供的,@Resource是 JSR-250 提供的 问题二:各种DI方式的优缺点 参考Spring官方文档,建议了如下的使用场景: 构造器注入: 强依赖性 (即必须使用此依赖), 不变性 (各依赖不会经常变动) Setter注入 : 可选 (没有此依赖也可以工作), 可变 (依赖会经常变动) Field注入 :大多数情况下尽量 少使用 字段注入,一定要使用的话, @Resource相对@Autowired 对IoC容器的 耦合更低 Field注入的缺点不能像构造器那样注入不可变的对象 依赖对外部不可见 ,外界可以看到构造器和setter,但无法看到私有字段,自然无法了解所需依赖 会导致 组件与IoC容器紧耦合 (这是最重要的原因,离开了IoC容器去使用组件,在注入依赖时就会十分困难) 导致 单元测试也必须使用IoC容器 ,原因同上 依赖过多时不够明显 ,比如我需要10个依赖,用构造器注入就会显得庞大,这时候应该考虑一下此组件是不是 违反了单一职责原则 问题三:为什么IDEA只对@Autowired警告 Field 注入虽然有很多的缺点,但是他的好处也是不容忽视的,那就是太方便了,使用构造器或者 setter 注入需要写业务无关的代码,而字段注入大幅简化了他们.并且大多数情况下,业务代码和框架都是绑定的,完全松耦合 只是理想的一种情况。 况且Java 领域 能替代 spring 框架的 框架 还没出生了。!!!!!!!! 那么问题来了,为什么IDEA只对@Autowired警告,却对@Resource视而不见呢? 其实 主要 就是前面提到的: @Autowired 是 Spring 提供的,它是 特定IoC提供的特定注解 , 这就导致了应用跟框架的强绑定 一旦使用了其他IOC框架,是不能够支持注入的,而 @Resource 是 JSR-250 提供的,它是 Java标准 ,我们使用的IoC容器应当去兼容它,这样即使更换容器,也可以正常工作。