1. 自定义初始化函数——属性方法注入
在Spring框架中调用一个对象时,系统会先生成其构造函数。代码如下:
Spring配置文件,在里面通过依赖注入为学生类(student.java)注入了属性值,ApplicationContext.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="Student" class="Student.student">
<property name="name">
<value>欧世乐</value>
</property>
<property name="age">
<value>20</value>
</property>
<property name="sex">
<value>男</value>
</property>
</bean>
</beans>
在学生类里面,有学生的姓名、年龄和性别,可以通过方法Print打印出来,student.java:
package Student;
public class student {
public student(){
System.out.println("构造函数调用");
}
private String name,sex,age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
public String getAge() {
return age;
}
public void setAge(String age) {
this.age = age;
}
public void Print(){
System.out.println(this.getName());
System.out.println(this.getSex());
System.out.println(this.getAge());
}
}
主模块调用,Main.java:
package MainModule;
import Student.student;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.FileSystemXmlApplicationContext;
public class Main {
public static void main(String[] args) {
ApplicationContext context=new FileSystemXmlApplicationContext("ApplicationContext.xml");
student student1=(student)context.getBean("Student");
student1.Print();
}
}
结果如下:
可以从结果里面看到,构造函数的确是会在Spring调用类的时候自动生成的,如果我们想要自定义一个初始化的方法,该如何做呢。
只需要在student类里面添加一个init方法,然后在Spring的配置文件里面进配置就可以了。
Student.java:
package Student;
public class student {
public student(){
System.out.println("构造函数调用");
}
public void init(){
System.out.println("初始化函数调用");
}
private String name,sex,age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
public String getAge() {
return age;
}
public void setAge(String age) {
this.age = age;
}
public void Print(){
System.out.println(this.getName());
System.out.println(this.getSex());
System.out.println(this.getAge());
}
}
Spring配置文件ApplicationContext.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="Student" class="Student.student" init-method="init">
<property name="name">
<value>欧世乐</value>
</property>
<property name="age">
<value>20</value>
</property>
<property name="sex">
<value>男</value>
</property>
</bean>
</beans>
结果如下:
那初始化方法就会在构造方法之后自动调用了,同理可以生成消亡方法
ApplicationContext.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="Student" class="Student.student" init-method="init" destroy-method="destroy">
<property name="name">
<value>欧世乐</value>
</property>
<property name="age">
<value>20</value>
</property>
<property name="sex">
<value>男</value>
</property>
</bean>
</beans>
虽然屏幕上没有打印出来,但是实际上析构方法的确运行了。
2. 构造方法注入
如果觉得属性方法注入比较麻烦,可以采用构造方法注入
Spring配置文件ApplicationContext如下:
<?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="Student" class="Student.student" init-method="init" destroy-method="destroy">
<property name="name">
<value>欧世乐</value>
</property>
<property name="age">
<value>20</value>
</property>
<property name="sex">
<value>男</value>
</property>
</bean>
<!--构造方法-->
<bean id="Student2" class="Student.student" init-method="init" destroy-method="destroy">
<constructor-arg index="0" type="java.lang.String">
<value>欧乐乐</value>
</constructor-arg>
<constructor-arg index="1" type="java.lang.String">
<value>男</value>
</constructor-arg>
<constructor-arg index="2" type="java.lang.String">
<value>18</value>
</constructor-arg>
</bean>
</beans>
上面的index是参数的意思,我们在student.java里面配置了一个构造方法,student(String name,String sex,String age),这里的index就是对应的里面的参数。
所以叫做构造方法注入。
student.java里面新增了一个带参数的构造器,就是为了和构造注入形成配合:
package Student;
public class student {
public student(){
System.out.println("构造函数调用");
}
public student(String name,String sex,String age){
this.name=name;
this.age=age;
this.sex=sex;
}
public void init(){
System.out.println("初始化函数调用");
}
public void destroy(){
System.out.println("析构函数");
}
private String name,sex,age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
public String getAge() {
return age;
}
public void setAge(String age) {
this.age = age;
}
public void Print(){
System.out.println(this.getName());
System.out.println(this.getSex());
System.out.println(this.getAge());
}
}
主模块调用,和老样子没什么区别,只是getBean的参数名字改一下
package MainModule;
import Student.student;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.FileSystemXmlApplicationContext;
public class Main {
public static void main(String[] args) {
ApplicationContext context=new FileSystemXmlApplicationContext("ApplicationContext.xml");
student student1=(student)context.getBean("Student2");
student1.Print();
}
}
结果如下
3. 区别
属性方法注入不需要知道对象的类型,只需要知道对象的属性名即可。
构造方法注入不需要知道对象的属性名,但是需要知道对象的类型。
4.单态
修改主模块代码,生成两个student类的对象,观察构造方法执行了几次。
main.java:
package MainModule;
import Student.student;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.FileSystemXmlApplicationContext;
public class Main {
public static void main(String[] args) {
ApplicationContext context=new FileSystemXmlApplicationContext(“ApplicationContext.xml”);
student student1=(student)context.getBean(“Student2”);
student1.Print();
student student2=(student)context.getBean(“Student2”);
student2.Print();
}
}
结果如下:
![在这里插入图片描述]()
可以看到构造方法只执行了一次。
这里说明声明两个对象后,如果不加说明,下一次对对象的操作是会影响到上一次对象的,也就是无法保留我们想要的结果,所以单态就是解决这个问题。
系统是默认为单态模式的,在单态模式下,同一类的对象只会生成一次,和其他同类对象共用,我们把scope改为prototype即可。
在Spring配置文件ApplicationContext里面声明单态:
ApplicationContext.xml:
~~~java
<?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="Student" class="Student.student" init-method="init" destroy-method="destroy" scope="prototype">
<property name="name">
<value>欧世乐</value>
</property>
<property name="age">
<value>20</value>
</property>
<property name="sex">
<value>男</value>
</property>
</bean>
<!--构造方法-->
<bean id="Student2" class="Student.student" init-method="init" destroy-method="destroy" scope="prototype">
<constructor-arg index="0" type="java.lang.String">
<value>欧乐乐</value>
</constructor-arg>
<constructor-arg index="1" type="java.lang.String">
<value>男</value>
</constructor-arg>
<constructor-arg index="2" type="java.lang.String">
<value>18</value>
</constructor-arg>
</bean>
</beans>
结果如下: