Spring DI依赖注入(2)用注解实现注入

目录

一、注解

1.将一个类声明为Bean的注解

2.属性装配

二、使用注解实现实体类的注入

三、使用注解实现三层架构注入

四、Bean的生命周期 

1.Bean的生命周期

2.案例代码演示

1.单例

2.多例(修改上述模式为prototype即可)



一、注解

1.将一个类声明为Bean的注解

        @Component:定义通用Bean的注解,可标注任意类为Bean。如果一个Bean不知道属于哪个层,可以使用@Component注解标注。

        @Repository:定义数据访问层Bean的注解。

        @Service:定义业务层Bean的注解。

        @Controller:定义控制层Bean的注解

2.属性装配

        @Autowired:Spring提供的注解,默认的注入方式为byType(按类型自动注入)

        @Qualifier(value = "属性名"):根据byName的方式自动装配,不能单独使用,配合@Autowired使用

        @Resource:JDK提供的注解,默认注入方式为byName(按名称自动注入),可以单独使用

        @Value:实体类属性赋值,读取.properties结尾的文件进行赋值

二、使用注解实现实体类的注入

1.以学生类为例,定义两个属性,加入有参和无参的构造方法

package com.apesource.pojo;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;

@Component(value = "student")
@Scope(ConfigurableBeanFactory.SCOPE_SINGLETON)
public class Student {
    @Value("${msg1}")
    private String stuName;
    @Value("${msg2}")
    private int stuAge;

    @Override
    public String toString() {
        return "Student{" +
                "stuName='" + stuName + '\'' +
                ", stuAge=" + stuAge +
                '}';
    }

    public Student() {
        System.out.println("通过无参构造方法创建实例化对象");
    }

    public Student(String stuName, int stuAge) {
        this.stuName = stuName;
        this.stuAge = stuAge;
    }
}

2.在resource路径下创建spring config格式的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"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd"

>
<!--    自动扫描-->
    <context:component-scan base-package="com.apesource"></context:component-scan>
<!--    加载读取路径-->
    <context:property-placeholder location="classpath:msg.properties"></context:property-placeholder>
</beans>

三、使用注解实现三层架构注入

1.从数据访问层开始,继承接口,重写方法


//接口
public interface Dao {
    public void save();
}
@Repository(value = "dao")
public class DaoImp implements Dao{

    @Override
    public void save() {
        System.out.println("数据访问层");

    }
}

2.业务层继承接口重写方法,注入数据访问层,并实现方法的调用

public interface IService {
    public void save();
}
@Service(value = "service")
public class ServiceImp implements IService {
//    @Autowired     //自动装配
//    @Qualifier(value = "daoImpCopy")    //按照名称装配(配合@Autowired)

    @Resource(name = "dao")   //按名称装配(单独使用)
    Dao dao;

    public void setDao(Dao dao) {
        this.dao = dao;
    }

    @Override
    public void save() {
        System.out.println("业务层");
        dao.save();
    }
}

3.控制层继承接口,重写方法并注入业务层属性

public interface IController {
    public void save();
}
@Controller(value = "controller")
public class ControllerImp implements IController {
    @Autowired
    IService service;

    public void setService(IService service) {
        this.service = service;
    }

    @Override
    public void save() {
        System.out.println("控制层");
        service.save();
    }
}

4.测试

public class Test01 {
    public static void main(String[] args) {
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("application.xml");
        IController controller = (IController) applicationContext.getBean("controller");
        controller.save();
    }
}

四、Bean的生命周期 

1.Bean的生命周期

1.实例化

2.属性赋值

3.初始化

        3.1接口初始化InitializingBean

        3.2属性初始化init-method

4.操作使用

5.销毁

        5.1接口销毁DisposableBean

        5.2属性销毁destory-method

2.案例代码演示

1.首先,构造一个实体类,在实体类中创建一个无参构造方法:

2.实体类实现初始化和销毁接口,重写接口和属性方法:

package com.apesource.pojo;

import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.InitializingBean;

public class Teacher implements InitializingBean, DisposableBean{
    private String tName;
    private int tAge;

    public Teacher() {
        System.out.println("通过无参构造方法实例化");
    }
    //属性赋值
    public void settName(String tName) {
        System.out.println("属性赋值");
        this.tName = tName;
    }

    public void settAge(int tAge) {
        this.tAge = tAge;
    }

    @Override
    public void destroy() throws Exception {
        System.out.println("接口销毁");
    }
    public void doDestroy(){
        System.out.println("属性销毁");
    }

    @Override
    public void afterPropertiesSet() throws Exception {
        System.out.println("接口初始化");
    }
    public void doInit(){
        System.out.println("属性初始化");
    }

    @Override
    public String toString() {
        return "Teacher{" +
                "tName='" + tName + '\'' +
                ", tAge=" + tAge +
                '}';
    }
}

3.在xml文件中配置相关信息:注入实体类、初始化方法和销毁方法

<!--    bean的生命周期-->
    <bean id="teacher" class="com.apesource.pojo.Teacher" init-method="doInit" destroy-method="doDestroy">
        <property name="tName" value="老师"></property>
        <property name="tAge" value="33"></property>
    </bean>

4.测试输出:

import com.apesource.pojo.Teacher;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
/*
* springIOC容器对bean管理
*/
public class Test01 {
    public static void main(String[] args) {
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("application.xml");
        //生命周期
        ClassPathXmlApplicationContext classPathXmlApplicationContext = new ClassPathXmlApplicationContext("application.xml");
        Teacher teacher = (Teacher) classPathXmlApplicationContext.getBean("teacher");
        System.out.println(teacher);
        classPathXmlApplicationContext.close();
}

测试结果:

五、Bean的作用域

Spring中,bean作用域用于确定那种类型的bean实例从Spring容器中返回给调用者。

作用域描述
singletonBean在IOC容器中只存在一个实例,无论是获取Bean还是装配Bean都是同一个对象
prototype每次对Bean的请求都会创建一个新的实例,无论获取Bean还是装配Bean,都是一个新的实例对象
request每次http请求都会创建新的Bean实例,请求和响应共享Bean(只能在SpringMVC框架中使用)
session用于会话的共享Bean(只能在SpringMVC框架中使用)
application在Context中定义一个Bean(只能在SpringMVC框架中使用)
websocket在HTTP WebSocket生命周期中定义一个Bean(只能在SpringMVC框架中使用)

1.单例

A.注解版

1.构造一个实体类并使用Compoent注入容器,在xml文件中添加读取路径;

package com.apesource.pojo;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;

@Component(value = "student")
@Scope(ConfigurableBeanFactory.SCOPE_SINGLETON)
public class Student {
    @Value("${msg1}")
    private String stuName;
    @Value("${msg2}")
    private int stuAge;

    @Override
    public String toString() {
        return "Student{" +
                "stuName='" + stuName + '\'' +
                ", stuAge=" + stuAge +
                '}';
    }

    public Student() {
        System.out.println("通过无参构造方法创建实例化对象");
    }

    public Student(String stuName, int stuAge) {
        this.stuName = stuName;
        this.stuAge = stuAge;
    }
}

2.在实体类上添加@Scope注解开启作用域的配置,设置工厂模式为单例,在xml中添加自动扫描配置文件;

<!--    自动扫描-->
    <context:component-scan base-package="com.apesource"></context:component-scan>

3.测试输出;

package com.apesource.test;

import com.apesource.controller.IController;
import com.apesource.pojo.Student;
import com.apesource.pojo.Teacher;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

/*
 * springIOC容器对bean管理
 */
public class Test01 {
    public static void main(String[] args) {
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("application.xml");
        //@Scope作用域
        Student student1 = (Student) applicationContext.getBean("student");
        Student student2 = (Student) applicationContext.getBean("student");
        System.out.println(student1==student2);
}

测试结果:

B.XML版

1.构造实体类

package com.apesource.pojo;

public class Student {
    private String stuName;
    private int stuAge;

    @Override
    public String toString() {
        return "Student{" +
                "stuName='" + stuName + '\'' +
                ", stuAge=" + stuAge +
                '}';
    }

    public Student() {
        System.out.println("通过无参构造方法创建实例化对象");
    }

    public Student(String stuName, int stuAge) {
        this.stuName = stuName;
        this.stuAge = stuAge;
    }

    public String getStuName() {
        return stuName;
    }

    public void setStuName(String stuName) {
        this.stuName = stuName;
    }

    public int getStuAge() {
        return stuAge;
    }

    public void setStuAge(int stuAge) {
        this.stuAge = stuAge;
    }
}

2.在xml中进行相关配置,设置scope="singleton";

<!--    bean的作用域-->
    <bean id="student" class="com.apesource.pojo.Student" scope="singleton">
        <property name="stuName" value="学生"></property>
        <property name="stuAge" value="18"></property>
    </bean>

3.测试输出;

package com.apesource.test;

import com.apesource.controller.IController;
import com.apesource.pojo.Student;
import com.apesource.pojo.Teacher;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

/*
 * springIOC容器对bean管理
 */
public class Test01 {
    public static void main(String[] args) {
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("application.xml");
        //@Scope作用域
        Student student1 = (Student) applicationContext.getBean("student");
        Student student2 = (Student) applicationContext.getBean("student");
        System.out.println(student1);
        System.out.println(student2);
        System.out.println(student1==student2);
}

2.多例(修改上述模式为prototype即可)

测试结果:

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

起个有趣的名字好难

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值