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();
    }
}

结果如下:

springboot有参构造函数怎么注册Component springboot构造函数注入_Java

可以从结果里面看到,构造函数的确是会在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>

结果如下:

springboot有参构造函数怎么注册Component springboot构造函数注入_Spring_02


那初始化方法就会在构造方法之后自动调用了,同理可以生成消亡方法

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();
    }
}

结果如下

springboot有参构造函数怎么注册Component springboot构造函数注入_依赖注入_03

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>

结果如下:

springboot有参构造函数怎么注册Component springboot构造函数注入_Spring_04