我正在查看一些现有的应用程序代码,由于那里的代码,我很困惑,这里是场景:
在课程ABC
中,我将自动装配为:
@Autowired
RestTemplate restTemplate;
然后在我的spring bean配置文件中,我将bean定义为:
<bean id="restTemplate" class="org.springframework.web.client.RestTemplate"/>
在班级ABC
中,我使用的是休息模板:
restTemplate.postForObject(url, requestObject, String.class);
我的问题是:
<小时/> 根据评论和答案,下面是简约的可重现代码,它表明即使我在bean配置文件中进行了自动布线和bean定义,我也可以运行该程序并且没有问题。
主要课程:
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.FileSystemXmlApplicationContext;
import org.springframework.stereotype.Component;
@Component
public class SpringTest {
@Autowired
Person person;
public static void main(String[] args) {
generalTest();
}
private static void generalTest() {
testApplicationContext();
}
private static void testApplicationContext() {
ApplicationContext applicationContext = new FileSystemXmlApplicationContext("bean.xml");
SpringTest springTest = (SpringTest) applicationContext.getBean("springTest");
if(springTest.person == null){
System.out.println("person is NULL");
} else{
System.out.println("person is not NULL");
}
}
}
Bean文件:
<?xml version = "1.0" encoding = "UTF-8"?>
<beans xmlns = "http://www.springframework.org/schema/beans"
xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation = "http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd">
<context:component-scan base-package="com.learn.stackoverflow.general"/>
<!-- as such below is useless because The use of <context:component-scan> implicitly enables the functionality of <context:annotation-config>.
There is usually no need to include the <context:annotation-config> element when using <context:component-scan>. -->
<context:annotation-config />
<bean id = "person" class = "com.learn.stackoverflow.general.Person" scope="singleton">
</bean>
</beans>
人员类:
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
@Component
@Scope(value="singleton")
public class Person implements InitializingBean, Human {
@Autowired
SpringTest springTest;
static{
System.out.println("Static initialization from Person");
}
{
System.out.println("Instance initialization from Person");
}
public Person(){
System.out.println("Constructor from Person");
}
public void sayHello(){
System.out.println("Hello");
}
@Override
public void afterPropertiesSet() throws Exception {
System.out.println("InitializingBean.afterPropertiesSet from Person");
}
@Override
public void breathe() {
System.out.println("person is breathing...");
}
}
输出为person is not NULL
答案 0 :(得分:2)
配置文件告诉Spring 创建一个ID为&#34; restTemplate&#34;其类型为org.springframework.web.client.RestTemplate。默认范围是bean的单个实例。
然后在代码中,由于存在一个类型 RestTemplate的bean,所以bean(其ID恰好为&#34; restTemplate&#34;是自动连接的。
&#34; restTemplate&#34;作为id或类属性,也有&#34; restTemplate&#34;因为它的名字并不重要。豆可以注入,因为它是相同类型的。 (并且因为那里只有1种类型。)
答案 1 :(得分:1)
@Autowired
不创建bean,它将采用与预期类型匹配的现有bean声明并将其放在字段中。在XML中你有你的bean声明,没有它你的bean将不存在(除非你使用Spring Boot,在这种情况下它可能会自动创建,如果它不存在)。
自JSR-299以来,您现在可以使用@Inject
而不是@Autowired
,如果您有最新版本的Spring和javax.inject依赖项。两者都完全相同,但@Inject更清晰。
答案 2 :(得分:0)
当IoC容器找到bean配置文件中定义的bean定义时,会使用相同的定义来注入实例,如果IoC容器找不到,那么它会创建一个实例并注入相同的内容。
下面是一个稍微调整过的示例,它演示了上述概念,您可以使用它来评论和取消注释bean配置文件中提到的bean定义。 请仔细阅读我的代码评论。
<强> SpringTest:强>
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.FileSystemXmlApplicationContext;
import org.springframework.stereotype.Component;
@Component
public class SpringTest {
@Autowired
Person person;
public static void main(String[] args) {
generalTest();
}
private static void generalTest() {
testApplicationContext();
}
private static void testApplicationContext() {
ApplicationContext applicationContext = new FileSystemXmlApplicationContext("C:\\E_Drive\\Projects\\Workspace\\Test\\CS101\\src\\com\\learn\\stackoverflow\\general\\bean.xml");
SpringTest springTest = (SpringTest) applicationContext.getBean("springTest");
if(springTest.person == null){
System.out.println("person is NULL");
} else{
System.out.println("person is not NULL");
springTest.person.sayHello(); // here output will be “Hello, ppj” if you keep the config file bean definition and when you remove that bean definition then output is “Hello, null”
}
}
}
Bean配置:
<?xml version = "1.0" encoding = "UTF-8"?>
<beans xmlns = "http://www.springframework.org/schema/beans"
xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation = "http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd">
<context:component-scan base-package="com.learn.stackoverflow.general"/>
<!-- once you get comment out below, IoC will instatiate a bean and will inject the same in SpringTest's autowiring of Person class -->
<!-- <bean id = "person" class = "com.learn.stackoverflow.general.Person" scope="singleton">
<constructor-arg name="name" value="ppj"></constructor-arg>
</bean> -->
</beans>
<强>人:强>
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
@Component
@Scope(value="singleton")
public class Person {
private String name;
@Autowired
SpringTest springTest;
public Person(){
System.out.println("Constructor from Person");
}
public Person(String name){
System.out.println("String Constructor from Person");
this.name = name;
}
public void sayHello(){
System.out.println("Hello, " + name);
}
}