Spring学习(三)Spring容器是如何创建对象的
默认情况下是使用类的无参构造器创建的
我们继续创建一个工程。
实体类User.java
package com.hj.pojo;
public class User {
private String name;
public User(){
System.out.println("User无参构造");
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public void show(){
System.out.println("name="+name);
}
}
然后同时配置beans.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="user" class="com.hj.pojo.User">
<property name="name" value="Spring"/>
</bean>
</beans>
然后直接在测试类里测试:
import com.hj.pojo.User;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class MyTest {
public static void main(String[] args) {
//获取spring的上下文对象
ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
//我们的对象现在都在spring中管理了,我们要使用,直接去取出来就可以了
//这个时候就已经走了无参构造方法了,说明对象已经被创建了
//说明对象在context的时候就已经被创建了
User bean = (User)context.getBean("user");
bean.show();
}
}
我们在User bean = (User)context.getBean(“user”);打断点可以查看到context里的内容,可以发现其实User类的对象在context里就已经有了,说明对象的创建在new ClassPathXmlApplicationContext("beans.xml");
这句上。
然后这次我们再把User.java中的无参构造注释掉,改成有参构造,其实在IDEA里就能看到很明显的区别了:
左边有个豆子并且豆子右下角有个m,点一下可以跳转到我们的beans.xml里。说明spring是走的无参构造。但是我们还是实验一下,把无参构造注释掉:
package com.hj.pojo;
public class User {
private String name;
// public User(){
// System.out.println("User无参构造");
// }
public User(String name){
this.name=name;
System.out.println("User有参构造");
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public void show(){
System.out.println("name="+name);
}
}
继续运行刚刚的测试类,发现直接报错:Caused by: java.lang.NoSuchMethodException: com.hj.pojo.User.<init>()
说创建失败,我们没有User类的构造方法。
那spring就没办法使用有参构造来使用了吗?这样会不会太不灵活了?spring有别的办法来做有参构造初始化。
spring使用有参构造器创建对象
打开spring的官方文档:https://www.docs4dev.com/amp/docs/zh/spring-framework/5.1.3.RELEASE/reference/core.html#beans,可以看到在依赖的这章节里,有对依赖注入详细解释。
我们在基于构造函数的依赖注入这一小节里可以找到如下的解释:
那么答案就很明显了,我们可以通过<constructor-arg>标签来让其使用有参构造器。
此时我们修改beans.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="user" class="com.hj.pojo.User">
<!--构造函数参数索引-->
<constructor-arg index="0" value="Spring"/>
</bean>
<bean id="user2" class="com.hj.pojo.User">
<!--构造函数参数类型匹配-->
<constructor-arg type="java.lang.String" value="Spring"/>
</bean>
<bean id="user3" class="com.hj.pojo.User">
<!--构造函数参数名称 name="参数名称"-->
<constructor-arg name="name" value="Spring"/>
</bean>
</beans>
然后再运行测试类,发现不再报错了!而且调用的是有参的构造器!
public class MyTest {
public static void main(String[] args) {
//获取spring的上下文对象
ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
//我们的对象现在都在spring中管理了,我们要使用,直接去取出来就可以了
//这个时候就已经走了无参构造方法了,说明对象已经被创建了
//说明对象在context的时候就已经被创建了
User bean = (User)context.getBean("user");
bean.show();
User bean2 = (User)context.getBean("user2");
bean2.show();
User bean3 = (User)context.getBean("user3");
bean2.show();
//User有参构造
//User有参构造
//User有参构造
//name=Spring
//name=Spring
//name=Spring
}
}
总结
1.默认使用无参构造创建对象
2.如果需要用有参构造,就必须用别的方式:
2.1 索引赋值
<bean id="user" class="com.hj.pojo.User">
<!--构造函数参数索引-->
<constructor-arg index="0" value="Spring"/>
</bean>
2.2 类型赋值
<bean id="user" class="com.hj.pojo.User">
<!--构造函数参数类型匹配-->
<constructor-arg type="java.lang.String" value="Spring"/>
</bean>
2.3 参数名称赋值
<bean id="user3" class="com.hj.pojo.User">
<!--构造函数参数名称 name="参数名称"-->
<constructor-arg name="name" value="Spring"/>
</bean>
2.4 引用另外的bean(官方文档的例子)
<beans>
<bean id="thingOne" class="x.y.ThingOne">
<constructor-arg ref="thingTwo"/>
<constructor-arg ref="thingThree"/>
</bean>
<bean id="thingTwo" class="x.y.ThingTwo"/>
<bean id="thingThree" class="x.y.ThingThree"/>
</beans>
3.在配置文件加载的时候,spring容器里面管理的对象就已经初始化了。相当于婚介网站,你注册时候就已经会在那里了,哪怕你不用,他都已经创建好了对象。
本章节代码
本章节代码 中的spring-03中