配置文件中Bean标签 和注解的形式替代xml配置 这两种配置方式 都要掌握
- 在上面的案例中,成功做到了把AccountService对象赋值给了AccountController的属性;它们之间的关系是由spring配置实现的;
- 这种优化方案其实就是依赖注入。
- 依赖注入是控制反转的一种表现方式。
依赖查找也是控制反转的一种表现方式
id: 唯一的标识 class: 类的全限定名称,如果没有空的构造方法,需要其他的配置
2. 配置文件spring02.xml
<bean id="account" class="com.itheima.pojo.Account" init-method="init"
destroy-method="destroy" scope="singleton/prototype"></bean>
<bean id="account" class="com.itheima.pojo.Account">
<property name="id" value="1"></property>
<property name="name" value="英国女王"></property>
<property name="money" value="30000000"></property>
</bean>
scope 属性可设置值
singleton[重点]: 单例模式,全局唯一,只会实例化一次, 默认为单例模式
prototype[重点]: 原型模式(多例模式),每次getBean都会实例化一个新的对象
request:请求范围
session:http Session范围
application:servletContext范围
websocket: websocket访问(网络套接字)
1. 单例模式 创建容器时创建对象,容器销毁时 对象销毁
2. 原型模式
创建容器时,对象不会创建,在第一次获取对象时创建对象
对象不会随着容器的销毁而销毁
3. init-method:指定初始化时执行的方法
4. destory-method:指定销毁时执行的方法,只对scope为singleton的bean有效
BeanFactory 才是 Spring 容器中的顶层接口。
ApplicationContext 是操作容器接口,是BeanFactory 的子接口。
创建和获取对象 剖析获取spring容器对象的方法
1. 根据id获取对象,返回的是Object对象,需要进行强制转换
context.getBean("account");
2. 根据class获取对象,返回Account类型对象,不需要进行强制转换
context.getBean(Account.class);
3. 根据id 和 class获取对象,返回Account类型对象,不需要进行强制转换(需要满足两个条件)
context.getBean("account", Account.class);
@Test
public void getBean(){
ApplicationContext context = new ClassPathXmlApplicationContext("spring02.xml");
Object obj = context.getBean("account");
Account account1 = (Account) obj;
System.out.println(account1);
Account account2 = context.getBean(Account.class);
System.out.println(account2);
Account account3 = context.getBean("account", Account.class);
System.out.println(account3);
context.close();
}
总结1. 注入set,list,array 属性,分别使用 set, list , array 标签;
因为三种标签都是单列数据,可以交换使用,建议按照对应标签配置
2. 注入map,properties 属性,分别使用 map,props 标签
因为都是键值对数据,可以交换使用,建议按照对应标签配置
1. <contxt:property-placeholder> 需要新增名称空间,具体看下图
2. 通过<contxt:property-placeholder> 标签加载属性文件
location属性指定 属性文件的位置
属性文件中如果有中文,需要指定加载的编码格式
3. 如果要加载多个属性文件,location属性中提供一个或多个位置作为逗号分隔的列表。
4. 加载类路径下的资源,需要添加字符串前缀:classpath:
通过set方法给account的属性赋值
1. property标签可以通过set方法给属性赋值
name 指定属性名称 value 给属性赋的值
如set方法不存在,配置文件会有编译错误 set方法一定要符合格式
创建其他人定义的对象时,有些属性没有定义set方法,我们也可以采用构造方法注入
通过构造方法给属性赋值
<constructor-arg index索引="0" type类型="java.lang.Integer" name="money" value参数名="比尔盖茨"></constructor-arg>
注入引用数据类型,总结注入引用数据类型:需要先用bean标签创建对象, 再使用ref引用对象
1日期类并添加set和get方法,修改toString方法
private Date birthday;
spring配置文件
<bean id="birthday" class="java.util.Date"></bean>
<bean id="account5" class="com.itheima.pojo.Account">
<property name="birthday" ref="birthday"></property>
</bean>
2注入 list,set, map ,array 类型的对象
spring配置文件
<bean id="account7" class="com.itheima.pojo.Account">
<property name="myStrs">
<array>
<value>mybatis</value>
<value>spring</value>
<value>springMVC</value>
</array>
</property>
<property name="myList">
<list>
<value>表现层</value>
<value>业务层</value>
<value>持久层</value>
</list>
</property>
<property name="mySet">
<set>
<value>模型层</value>
<value>视图层</value>
<value>控制层</value>
</set>
</property>
<property name="myMap">
<map>
<entry key="M" value="Model"></entry>
<entry key="V" value="View"></entry>
<entry key="C" value="Controller"></entry>
</map>
</property>
<property name="myProps">
<props>
<prop key="M">Model</prop>
<prop key="V">View</prop>
<prop key="C">Controller</prop>
</props>
</property>
</bean>
Account.java 中添加属性
private String[] myStrs;
private List<String> myList;
private Set<String> mySet;
private Map<String,String> myMap;
private Properties myProps;
代码 data.properties
account.id=1
account.name=zhangsan
account.money=3000000
<?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:p="http://www.springframework.org/schema/p"
xmlns:contxt="http://www.springframework.org/schema/context"新增名称空间
xsi:schemaLocation="http://www.springframework.org/schema/beans
https://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">
<context:property-placeholder location="classpath:data.properties"
file-encoding="UTF-8"></contxt:property-placeholder>
<bean id="account9" class="com.itheima.pojo.Account">
<property name="id" value="${account.id}"></property>
<property name="name" value="${account.name}"></property>
<property name="money" value="${account.money}"></property>
</bean>
</beans>
注入Bean(@Autowired)启动注解扫描,加载类中配置的注解项<context:component-scan base-package="packageName"/>
Bean的定义(@Component设置该类为spring管理的bean)
1@Component @Controller @Service @Repository
- @Controller、@Service 、@Repository是@Component的衍生注解,功能同@Component
- @Controller 用于Controller层的类 :表现层
- @Service 用于Service层的类: 业务层
- @Repository 用于Dao层的类: 持久层(一般不写)
- 相关属性 value(默认):定义bean的访问id , 默认的id名称为 "简单类名,首字母小写"
2注入Bean@Autowired @Autowired、@Qualifier、@Resource
可以用在属性上和set方法上, 如果写在属性上,可以没有set方法
自动装配,设置属性的对象或对方法进行传参(从IOC容器查找对象,赋值 给属性)
@Autowired 按类型装配,一般生产中都使用它,由spring提供的,只有引入spring包才可使用。
@Qualifier 可以指定bean的id,一般用于有多个同一类型bean的场景(必须配合@Autowired使用)。
@Resource=@Autowired +@Qualifier
注解的方式注入bean,不需要setter方法
@Autowiredrequired:定义该属性是否允许为null,默认true
Qualifier value:需要注入的bean的id
@Primary 类注解设置bean的优先级,也可以用于方法上,配合@Bean使用
@Autowired默认按类型装配,当出现相同类型的bean,使用@Primary提高按类型自动装配的优先级,程序就不会报错了。
@Primary
@Component
public class ClassName{}
@Scope 类注解,相当于<bean>标签的scope属性
@Scope("prototype")
public class ClassName{}
```-