1、Spring 配置文件

1.1 别名

当类名过长需要简写的时候可以使用别名

<!--如果添加了别名 我们可以用别名或者原名取到这个对象-->
<alias name="user" alias="userNew"/>

1.2 Bean的配置

  • id: bean唯一标识符 也就是相当于变量名/对象名
  • class: bean对象所指定类的全类名(包名加类名)
  • **name:**别名 比alias高级 可以取多个别名 name="newName,newName2"或者 name="newName newName2"
<bean id="user" class="cn.mianju.pojo.User" name="user2 u2,u3;u4">
    <property name="name" value="xf"/>
</bean>

1.3 import(导入)

一般用于团队开发 可以将多个配置文件导入合并为一个

<import resource="applicationContext.xml"/>

导入后 只读取一个就可以使用多个配置文件中的bean

2、DI 依赖注入

2.1 构造器注入

构造器注入就是通过Bean去创建对象,创建对象的时候通过类中的构造方法来注入

<?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="cn.mianju.pojo.User">
<!--        <property name="name" value="xf"/>-->
<!--        <constructor-arg index="0" value="xf"/>-->
<!--        <constructor-arg type="java.lang.String" value="xf"/>-->
        <constructor-arg name="name" value="xf"/>
        <!--根据参数名来传入参数-->
    </bean>

</beans>

2.2 Set注入【重点*】

  • 依赖注入:Set注入
    • 依赖:Bean对象的创建依赖于容器
    • 注入:Bean对象中的所有属性 由容器来注入

复杂类型搭建:

private String name;
private Teacher teacher;
private String[] books;
private List<String> hobbies;//集合类型注入
private Map<String, String> card;
private Set<String> games;
private String wife;
private Properties info;

注入方法:

<?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="teacher" class="cn.mianju.pojo.Teacher"/>

    <bean id="user" class="cn.mianju.pojo.User">
        <!--普通方式注入:键名和值-->
        <property name="name" value="xf"/>
        <!--Bean注入:引用类型 ref方法-->
        <property name="teacher" ref="teacher"/>

        <!--以下为集合类型注入-->

        <!--数组注入 ref-->
        <property name="books">
            <array>
                <value>Chinese</value>
                <value>Math</value>
                <value>English</value>
            </array>
        </property>
        <!--List注入-->
        <property name="hobbies">
            <list>
                <value>唱</value>
                <value>跳</value>
                <value>rap</value>
            </list>
        </property>
        <!--Map注入-->
        <property name="card">
            <map>
                <entry key="studentCardId" value="1"/>
            </map>
        </property>
        <!--Set注入-->
        <property name="games">
            <set>
                <value>永劫无间</value>
                <value>英雄联盟</value>
            </set>
        </property>
        <!--Null 空值注入-->
        <property name="wife">
            <null/>
        </property>
        <!--Properties注入-->
        <property name="info">
            <props>
                <prop key="学号">14</prop>
            </props>
        </property>
    </bean>


</beans>

2.3 拓展方式注入

**c-namespace **和 p-namespace 这是一种语法糖 简化配置的一个方法

p-namespace:需要加一条依赖在头文件xmlns:p="http://www.springframework.org/schema/p"

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:p="http://www.springframework.org/schema/p"
       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">

    <!--p:property 可以直接使用这种方式注入 叫 p命名空间注入-->
    <bean id="user" class="cn.mianju.pojo.User" p:name="xf"/>

</beans>

c-namespace:需要加一条依赖在头文件xmlns:c="http://www.springframework.org/schema/c"

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:p="http://www.springframework.org/schema/p"
       xmlns:c="http://www.springframework.org/schema/c"
       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="cn.mianju.pojo.User" p:name="xf"/>-->
    
    <!--c:constructor 可以直接使用这种方式注入 叫 c命名空间注入-->
    <bean id="user" class="cn.mianju.pojo.User" c:name="xf"/>

</beans>

p命名空间(p-namespace)也是属于Set注入,而c命名空间(c-namespace)则是属于构造器注入

注意点:p命名空间(p-namespace)和 c命名空间(c-namespace)不能直接使用,需要导入前置约束

p-namespace:xmlns:p="http://www.springframework.org/schema/p"

c-namespace:xmlns:c="http://www.springframework.org/schema/c"

3、 Bean的作用域

Bean的作用域(Bean scope)

这是个面试高频问题

singleton在spring IoC容器仅存在一个Bean实例,Bean以单例方式存在,bean作用域范围的默认值。
prototype每次从容器中调用Bean时,都返回一个新的实例,即每次调用getBean()时,相当于执行newXxxBean()。
request每次HTTP请求都会创建一个新的Bean,该作用域仅适用于web的Spring WebApplicationContext环境。
session同一个HTTP Session共享一个Bean,不同Session使用不同的Bean。该作用域仅适用于web的Spring WebApplicationContext环境。
application同一个HTTP Session共享一个Bean,不同Session使用不同的Bean。该作用域仅适用于web的Spring WebApplicationContext环境。

更换作用域的方法是:

<?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="cn.mianju.pojo.User" scope="singleton"/>

</beans>

bean标签中的scope属性就是选择作用域的

而默认的作用域是singleton 也就是单例模式

单例模式可能会存在线程不安全、数据不一致的问题

原型模式的话就会大量的占用资源

如果是单线程模式还是推荐使用单例

4、Bean的自动装配

  • 自动装配是Spring满足Bean依赖的一种方式
  • Spring会在上下文中自动寻找,并自动给bean装配属性!

在Spring中有三种装配方式:

  • 在xml中显示的配置
  • 在Java代码中显示的配置
  • 隐式的自动装配Bean

4.1 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="cat" class="cn.mianju.pojo.Cat"/>
    <bean id="dog" class="cn.mianju.pojo.Dog"/>

    <bean id="person" class="cn.mianju.pojo.Person">
        <property name="name" value="xf"/>
        <property name="cat" ref="cat"/>
        <property name="dog" ref="dog"/>
    </bean>

</beans>

自动装配:

根据名字来自动装配

<?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="cat" class="cn.mianju.pojo.Cat"/>
    <bean id="dog" class="cn.mianju.pojo.Dog"/>

    <bean id="person" class="cn.mianju.pojo.Person" autowire="byName"/>

</beans>

根据类型来自动装配

<?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 class="cn.mianju.pojo.Cat"/>
    <bean class="cn.mianju.pojo.Dog"/>

    <bean id="person" class="cn.mianju.pojo.Person" autowire="byType"/>

</beans>

小结

  • **byName:**会自动在容器上下文中查找,和自己对象set方法后面的值对应的beanId

    • 需要保证所有Bean的ID唯一并且这个bean需要和自动注入的属性名一致
  • **byType:**会自动在容器上下文中查找,和自己对象属性类型相同的bean

    • 需要保证所有Bean的类型唯一并且这个bean需要和自动注入的属性类型一致 还可以没有ID!

4.2 使用注解实现自动装配

要使用注解进行自动装配,首先要去applicationContext.xml中去添加前置约束

xmlns:context="http://www.springframework.org/schema/context

http://www.springframework.org/schema/context
https://www.springframework.org/schema/context/spring-context.xsd

添加约束后在文件中添加一行对注解的支持

<context:annotation-config/>

然后就可以使用注解进行自动装配

<?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:annotation-config/>

</beans>

4.2.1 @Autowired 【常用】

使用 @Autowired 注解来进行自动装配

@Autowired的特性是:

  • 先使用byType方式去寻找可自动装配的,找不到后再使用byName方式去寻找
  • 此注解可以放在类的属性上,也可以放在类的setting
  • 如果将此注解放在属性上 可以不写set方法
  • 前提是自动装配的属性在IoC容器中存在(也就是说在applicationContext.xml中注册了)
package cn.mianju.pojo;

import org.springframework.beans.factory.annotation.Autowired;

public class Person {
    
    private String name;
    @Autowired
    private Dog dog;
    @Autowired
    private Cat cat;


    public Dog getDog() {
        return dog;
    }

    public void setDog(Dog dog) {
        this.dog = dog;
    }

    public Cat getCat() {
        return cat;
    }
    
    public void setCat(Cat cat) {
        this.cat = cat;
    }
}

4.2.2 @Qualifier

那如果有多个同类型且无法通过byName去寻找的时候,使用**@Autowired**无法达到我们的需求

我们可以再添加一个**@Qualifier**的注解

例:

  • applicaitonContext.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:annotation-config/>
      
          <bean id="cat" class="cn.mianju.pojo.Cat"/>
          <bean id="cat2" class="cn.mianju.pojo.Cat"/>
          <bean id="dog" class="cn.mianju.pojo.Dog"/>
          <bean id="dog2" class="cn.mianju.pojo.Dog"/>
          <bean id="person" class="cn.mianju.pojo.Person"/>
      
      </beans>
      
  • Person类:

    • package cn.mianju.pojo;
      
      import org.springframework.beans.factory.annotation.Autowired;
      import org.springframework.beans.factory.annotation.Qualifier;
      
      public class Person {
          @Autowired
          @Qualifier(value = "dog")
          private Dog dog;
      
          @Autowired
          @Qualifier(value = "cat")
          private Cat cat;
      
      
          public Dog getDog() {
              return dog;
          }
      
      
          public Cat getCat() {
              return cat;
          }
      
      }
      

使用 @Qualifier 注解可以指定一个value也就是id

4.2.3 @Resource

使用 @Resource 注解去进行自动装配的话和@Autowired的作用类似 但是

  • @Resource 没有 @Autowired 的搜索范围广,因为是默认通过name属性来查找的
  • @Resource 不需要导入 Spring的包,是一个jdk8的原生注解,在jdk8之后取消了这个注解
  • 也是通过类型或者id其中一个来查找的 更推荐使用 @Autowired

如果 @Resource 在多个同类型 并且 id对不上的情况下,会寻找不到,这个时候加一个参数就可以

例:

public class Person {

    @Resource(name = "dog1")
    private Dog dog;
    
    @Resource(name = "cat1")
    private Cat cat;
    
}

小结:

  • @Resource@Autowired 的区别
    • 都是用来自动装配 且 都可以放在属性的字段上
    • @Autowired 先通过byType再通过byName装配
    • @Resource 先通过byName再通过byType来装配
上一篇 下一篇