Open bitfishxyz opened 5 years ago
@Inject
(javax.inject.Inject
)是JSR-299提出的标准,用来规范依赖注入的语法。
而@Autowired是Spring自带的用于依赖注入的注解。
Spring设计者选择让@Autowired兼容@Inject,二者可以基本互换。唯一的区别是@Autowired比@Inject多了一个required
属性。
如果你想使用@Inject,需要引入下面的依赖
<dependency>
<groupId>javax.inject</groupId>
<artifactId>javax.inject</artifactId>
<version>1</version>
</dependency>
那么,这两个注解我用谁呢?就想豆腐脑是甜的还是咸的,SO网友有激烈的讨论。
https://stackoverflow.com/questions/19896870/why-is-my-spring-autowired-field-null
接上面的例子,我通过这样的方式创建熊猫守望者,为什么发现结果是null?
PandaWatcherAnnotation pandaWatcher = new PandaWatcherAnnotation();
System.out.println(pandaWatcher.getPanda());
因为@Autowired之类的注解必须由IOC容器来管理才会生效,你要是通过new的方式创建,这其实是跳过了依赖注入的阶段,所以结果是null。
https://stackoverflow.com/questions/17193365/what-in-the-world-are-spring-beans
我已经非常熟练的使用Spring了,但我还是搞不清楚Bean究竟意味着什么,谁能解释一下?
你的应用程序中,被Sping Ioc容器管理的对象都称之为Bean。每个Bean的实例化、组装。。。都是由Spring来管理的。
https://stackoverflow.com/questions/243385/beanfactory-vs-applicationcontext
我知道ApplicationContext 继承自 BeanFactory,但是到底如何选择呢?
Sping的官方文档以及有了解释了: 3.8.1. BeanFactory or ApplicationContext?. 我来总结下
Bean Factory
Application Context
So if you need any of the points presented on the Application Context side, you should use ApplicationContext.
https://stackoverflow.com/questions/129207/getting-spring-application-context
很简单,直接自动装配就行了
@Getter @Setter
@NoArgsConstructor
public class Sheep {
private String name;
@Autowired
private ApplicationContext context;
}
给bean一个ApplicationContext类型的属性,然后自动装配就行了。
public class SheepAnnotationTest {
private static ApplicationContext context;
@BeforeClass
public static void getContext(){
context = new ClassPathXmlApplicationContext("ioc/annotation/spring.xml");
}
@Test
public void autowire(){
Sheep sheep = context.getBean("sheep", Sheep.class);
System.out.println(sheep.getContext() == context);
// true
}
}
或者可以让我们的bean实现ApplicationContextAware这个接口
@Getter @Setter
@NoArgsConstructor
public class Fish implements ApplicationContextAware {
private String name;
private ApplicationContext context;
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
this.context = applicationContext;
}
}
这样容器在初始化的时候就会调用这个方法,并且把ApplicationContext作为参数传递进去
Fish fish = context.getBean("fish", Fish.class);
System.out.println(fish.getContext() == context);
// true
https://stackoverflow.com/questions/5269450/multiple-packages-in-contextcomponent-scan-spring-config
类似于下面这样
<context:component-scan base-package="x.y.z.service, x.y.z.controller" />
<context:annotation-config>
and<context:component-scan>
之间有什么区别?https://stackoverflow.com/questions/7414794/difference-between-contextannotation-config-vs-contextcomponent-scan)
<context:annotation-config>
表明,对于已经注册到容器中的bean,Spring将会监测这些bean上的注解,并作出处理假如有这样的类,动物园的一只大熊猫
然后有一个熊猫守望者:
在熊猫守望者身上有@Autowire这个注解。
然后我们写出这样的配置文件
那么大家觉得我通过容器创建pandaWatcher后,它的属性有没有被注入panda?
答案是否定的,我们需要在配置文件中开启注解模式后,Spring才会处理这个注解。写成这样就行了
而
<context:component-scan>
这个配置是开启注解扫描。有了它之后你就不用再配置文件中配置bean了,可以直接在Java代码中给相关的类标注为@Component
@Repository
。。。然后呢,你开启
<context:component-scan>
之后,<context:annotation-config>
默认也是会被开启的。