spring对象容器使用

前言

spring是一个开源的控制反转和面向切面的容器框架

一、控制反转(IOC)和依赖注入(DI)

  1. 两者关系:依赖注入是控制反转的重要部分,它主要目的是简化企业开发。
  2. 控制反转:是应用本身不负责依赖对象的创建以及维护,依赖对象的创建以及维护是由外部容器负责的。
  3. 依赖注入:在运行期间,由外部容器动态地将依赖对象注入到组件中。

二、为何要引入控制反转和依赖注入?

1.一个简单实例说明:如果一个接口实现多个功能,怎样才能让不同的调用者按照自己的意愿随意调用实现接口的类中的方法,避免了接口组件这件的耦合性高的缺点,业务实现不灵活,这就是引入原因

假设一个接口要实现使用删除的方法,这个接口有两个实现类实现重写接口中的方法(示例):
接口

public interface StudentDao {
    
    
    public void delete();
}

两个实现类

public class StudentDaoImplMysql implements StudentDao{
    
    
    @Override
    public void delete() {
    
    
        System.out.println("使用mysql数据库删除数据");
    }
}
public class StudentDaoImplOracle implements StudentDao{
    
    
    @Override
    public void delete() {
    
    
        System.out.println("使用oracle数据库删除数据");
    }
}

服务层

public class StudentService {
    
    

    private StudentDao studentDao;
	//主要的修改在于利用服务层的构造方法写入接口引用,可以传入实现接口的多个不同实现类中的删除功能,使用哪一个接口实现类的完全取决于使用者,极大地降低了代码的耦合性,更具有灵活性
    public StudentService(StudentDao studentDao){
    
    
        this.studentDao = studentDao;
    }
    public void delete(){
    
    
        studentDao.delete();
    }
}

测试类

public class Test {
    
    
    public static void main(String[] args) {
    
    
        StudentService service = new StudentService(new StudentDaoImplOracle());
        service.delete();
    }
}

三、控制反转和依赖注入的高级使用

(一)、maven项目的创建

1、 在所需要创建基本的一个maven项目的所需配置环境之后,在创建好生成的maven的下的pom.xml配置文件中,还需要添加配置maven配置信息,在标签 中放入maven配置参数地址

主要摘取的配置信息

<dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-webmvc</artifactId>
            <version>5.3.5</version>
</dependency>

2、 之后相关的配置文件会帮在该maven项目下主动生成关联的maven的所有jar包,不用我们手动添加到项目中

3、maven项目下的src下有两个包,一个包是main中的java(主要是用来书写类代码;其次是名为resources,其下是存放xml配置文件);另一个包是test,其下的java包主要是存放测试类

(二)、ClassPathXmlApplicationContext类的使用(利用spring中获取对象)

对于多个spring容器访问有以下两种方式

  • ApplicationContext context = new ClassPathXmlApplicationContext(“applicationContext*.xml”);需要注意的是*是改配置文件下的所有配置文件,但是不知道顺序,先后不确定
  • 在配置文件中添加import resource="applicationContext.xml"标签,但这个有先后顺序

实现使用该类得到spring中的对象需要与resources包下书写关于封装对象的配置文件

spring的xml配置文件:主要是从实体类中通过 bean标签下,配置关于访问类的一些属性

(1)配置一个实体student类标签如下:

 <bean id="student" class="com.entity.Student" lazy-init="true" scope="prototype" init-method="init" destroy-method="destroy">
<!--id表示唯一标识的值,获取对象名称;class的属性表示该类所在包位置路径,类名,容器会根据全类名路径字符串反射创建对象;
 lazy-init是Spring中延迟加载bean的属性,默认是false,表示立退加载,
 当spring启动时,立刻进行实例化,而设置为true表示延迟创建对象,
 在使用该对象时才创建并初始化,缩短spring容器启动时间,节省内存空间;scope="prototype":
 每次调用都创建新的对象,默认是singleton单例;destroy-method="destroy",对象销毁时调用的方法,只执行一次-->
        <property name="id" value="1"/>
<!--property标签是为实体类下的属性赋值,其中的name属性相当于实体类中的setXxx方法进行赋值-->
        <property name="name" value="张三"/>
        <property name="age" value="22"/>
</bean>

(2)除了一些基本数据类型的实体类,对于一些其他的数据类型包括字符串、集合、数组、配置文件等都是可以通过xml配置文件bean标签进行配置实现访问
配置含有一下集中数据类型的实体类配置文件

 <bean id="bean" class="com.entity.Bean">
        <property name="intValue" value="1"/>
        <property name="strValue" value="张三"/>
        <property name="arrayValue">
            <array>
                <value>张三</value>
                <value>李四</value>
                <value>王五</value>
            </array>
        </property>
        <property name="listValue">
            <list>
                <value>张三1</value>
                <value>李四1</value>
                <value>王五1</value>
            </list>
        </property>
        <property name="setValue">
            <set>
                <value>张三2</value>
                <value>李四2</value>
                <value>王五2</value>
            </set>
        </property>
        <property name="mapValue">
            <map>
                <entry key="CN" value="中国"/>
                <entry key="EN" value="美国"/>
                <entry key="RU" value="俄罗斯"/>
            </map>
        </property>
        <property name="propValue">
            <props>
                <prop key="CN">中国</prop>
                <prop key="EN">英国</prop>
                <prop key="RU">日本</prop>
            </props>
        </property>
    </bean>

实现访问类

 //把对象创建的工作交给spring容器集中创建,要用的时候直接去spring容器中去拿
 //1、加载spring配置文件,启动spring容器,创建对象,每一个类默认单例模式创建,默认在加载文件时创建
 ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
       /*ClassPathXmlApplicationContext()---->src下的类路径*/
       //2、从spring容器中获取对象
        Student student = (Student)context.getBean("student");
        Student s = context.getBean(Student.class);
        //3、使用对象
        System.out.println("student = " + student);
        System.out.println("s = " + s);
        System.out.println(s==student);/*true,同一个对象引用*/
        System.out.println("===========");
        Bean bean = (Bean)context.getBean("bean");
        System.out.println(bean);
        System.out.println("bean = " + bean.getIntValue());
        System.out.println("bean = " + bean.getStrValue());
        Arrays.stream(bean.getArrayValue()).forEach(v-> System.out.println("v = " + v));
       // System.out.println("bean = " +  Arrays.stream(bean.getArrayValue()));
        System.out.println("bean = " + bean.getListValue());
        System.out.println("bean = " + bean.getSetValue());
        System.out.println("bean = " + bean.getMapValue());
        System.out.println("bean = " + bean.getPropValue());

(3)实体类中以其他实体类引用作为引用类型使用
代码如下

public class Bean1 {
    
    
    private Bean2 bean2;
    @Resource
    private Bean3 bean3;
    public Bean1() {
    
    
    }
    public Bean2 getBean2() {
    
    
        return bean2;
    }
    public void setBean2(Bean2 bean2) {
    
    
        this.bean2 = bean2;
    }
    public Bean3 getBean3() {
    
    
        return bean3;
    }
    public void setBean3(Bean3 bean3) {
    
    
        this.bean3 = bean3;
    }
    public Bean1(Bean2 bean2, Bean3 bean3) {
    
    
        this.bean2 = bean2;
        this.bean3 = bean3;
    }
    @Override
    public String toString() {
    
    
        return "Bean1{" +
                "bean2=" + bean2 +
                ", bean3=" + bean3 +
                '}';
    }
}
public class Bean2 {
    
    
}
public class Bean3 {
    
    
}

(4)关于实体类之间的引用类型使用,通过从spring容器中实现实体类对象的创建和使用

  • set方法注入

 <bean id="bean1" class="com.entity.Bean1">
       <property name="bean2" ref="bean2"/>
        <property name="bean3" ref="bean3"/>
 </bean>
 <!--创建bean1对象时,也把关联的bean2、bean3对象引用也创建了-->
  • 构造方法注入

<bean id="bean1" class="com.entity.Bean1">
        <constructor-arg index="0" ref="bean2"/>
        <constructor-arg index="1" ref="bean3"/>
 </bean>
 <!--创建bean1对象时,也把关联的bean2、bean3对象引用也创建了-->
  • 注解模式

这个需要配置一些参数链接
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:context="http://www.springframework.org/schema/context"
<!--使用到context相关的标签要添加的参数-->
       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
       http://www.springframework.org/schema/context
 <!--使用到context相关的标签要添加的参数-->
 http://www.springframework.org/schema/context/spring-context.xsd">
  <!--使用到context相关的标签要添加的参数-->
开启注解模式
注解标签以及关联对象引用
<context:annotation-config/>
<bean id="bean2" class="com.entor.entity.Bean2"/>
<bean id="bean3" class="com.entor.entity.Bean3"/>

实体类前要注解@Component

具体位置如下
@Component(value = "bean1")
public class Bean1 {
    
    
	 @Resource/*指定ID属性值查找*/
    private Bean2 bean2;
    @Resource
    private Bean3 bean3;
    public Bean1() {
    
    
    }
    public Bean2 getBean2() {
    
    
        return bean2;
    }
    public void setBean2(Bean2 bean2) {
    
    
        this.bean2 = bean2;
    }
    public Bean3 getBean3() {
    
    
        return bean3;
    }
    public void setBean3(Bean3 bean3) {
    
    
        this.bean3 = bean3;
    }
    public Bean1(Bean2 bean2, Bean3 bean3) {
    
    
        this.bean2 = bean2;
        this.bean3 = bean3;
    }
    @Override
    public String toString() {
    
    
        return "Bean1{" +
                "bean2=" + bean2 +
                ", bean3=" + bean3 +
                '}';
    }
}
@Component
public class Bean2 {
    
    
}
@Component
public class Bean3 {
    
    
}
  • 组件包扫描形式
    指定包以及子包路径下的所有被注解@Controller、@Service、@Repository、@Component标识过的类,都创建对象
    配置标签如下,就不需要添加bean标签进行利用反射进行获取类对象,普通类了
 <context:component-scan base-package="com.entor.entity"/>

注解的介绍和作用

  • @Resource:作用在属性上,默认根据属性名称去配置文件中查找对应id名称的bean,创建对象后赋值给该属性变量。 如果找不到,则根据属性类型去查找bean,如果再找不到或者有多个则报错。
  • @Autowired&@Qualifier :作用在属性上,默认根据属性类型去配置文件查找对应的bean,创建对象后赋值给该属性变量。如果找不到或者找到多个,则根据属性名称去查找bean,如果找不到则报错。一般配合@Qualifier指定名称查找bean,如果找不到则报错。
  • @Resource(name = “String”)& @Qualifier(value = “String”): 注解可以指定name属性,则根据指定的名称去配置文件查找,一旦指定了名称,只会根据指定的名称查找,如果找不到则报错
  • @Controller (用在控制层类上面)&@Service (用在业务层类上面)&@Repository (用在数据访问层类上面):相当于在配置文件中配置bean,id默认是该类首字母小写,也可以指定名称
  • @Component(万能区分类):除了 @Controller、@Service、@Repository 之外的不好区分的类上面用这个注解,也是相当于在配置文件中配置bean,id默认是该类首字母小写,也可以指定名称

猜你喜欢

转载自blog.csdn.net/wearewell258369/article/details/115181975
今日推荐