Spring 配置文件
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来装配