Spring基于XML的配置
拷贝jar包到lib目录下
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.0.2.RELEASE</version>
</dependency>
</dependencies>
创建一个Bean.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">
<!--把对象的创建交给spring来管理-->
<!--配置service-->
<bean id="accountService" class="com.itheima.service.impl.AccountServiceImpl"></bean>
<!--配置dao-->
<bean id="accountDao" class="com.itheima.dao.impl.AccountDaoImpl"></bean>
</beans>
bean 标签:用于配置让spring创建对象,并且存入ioc容器
id属性:对象唯一标识
class属性:指定要创建对象的全限定类名
测试
public class Client {
//获取spring的Ioc核心容器并根据id获取对象
public static void main(String[] args) {
//1.获取核心容器对象
ApplicationContext ac = new ClassPathXmlApplicationContext("bean.xml");
//2.根据id获取Bean对象
IAccountService as = (IAccountService)ac.getBean("accountService");
IAccountDao adao = ac.getBean("accountDao",IAccountDao.class);
System.out.println(as);
System.out.println(adao);
}
BeanFactory和ApplicationContext的区别
BeanFactory是Spring容器的顶层接口。
ApplicationContext:它在创建核心容器时,创建对象采取的策略是采用立即加载的方式,也就是说,只要一读取完配置文件就马上创建配置文件中配置的对象,
对于单例对象适用,开发中常采用此接口。
BeanFactory: 它在构建核心容器时,创建对象的策略是采用延迟加载的方式,什么时候获取 id 对象了,什么时候就创建对象。对于多例对象适用。
ApplicationContext的三个常用实现类:
ClassPathXmlApplicationContext: 它可以加载路径下的配置文件,要求配置文件必须在路径下,否则加载不了(推荐)。
FileSystemXmlApplicationContext:它可以加载磁盘任意路径下的配置文件(必须有访问权限)。
AnnotationConfigApplicationContext:它是用于读取注解创建容器的,是明天的内容。
**
Bean标签和管理对象细节
bean标签
用于配置对象让spring来创建,默认情况下调用的是类的无参构造方法,没有 无参构造方法则不能创建成功。
scope属性:
作用:用于指定bean的作用范围
取值: 常用的就是单例的和多例的
singleton:单例的(默认值)
prototype:多例的
request:作用于web应用的请求范围
session:作用于web应用的会话范围
global-session:作用于集群环境的会话范围(全局会话范围),当不是集群环境时,它就是session
init-method:指定类的初始化方法名称
destroy-method:指定类的销毁方法名称
bean对象的生命周期
单例对象
出生:当容器创建时对象出生
活着:只要容器还在,对象一直活着
死亡:容器销毁,对象消亡
总结:单例对象的生命周期和容器相同
多例对象
出生:当我们使用对象时spring框架为我们创建
活着:对象只要是在使用过程中就一直活着。
死亡:当对象长时间不用,且没有别的对象引用时,由Java的垃圾回收器回收
创建Bean对象的三种方式
第一种方式:使用默认构造函数创建。
第二种方式: 使用普通工厂中的方法创建对象(使用某个类中的方法创建对象,并存入spring容器)
实例工厂类
/**
*模拟一个工厂类,该类可能存在于jar包中,无法通过修改源码的方式来提供默认构造函数
*
*/
public class InstanceFactory {
public IAccountService getAccountService() {
return new AccountServiceImpl();
}
}
配置方式
<bean id = "instanceFactory" class = "com.itheima.factory.InstanceFactory"></bean>
<bean id = "accountService"
factory-bean="instanceFactory" factory-method="getAccountService"></bean>
这种方法是:先把工厂的创建交给spring来管理,然后再使用工厂的bean来调用里面的方法。
factory-bean:用于指定实例工厂bean的id。
factory-method:指定实例工厂中创建对象的方法。
第三种方式:使用工厂中的静态方法创建对象(使用某个类中的静态方法创建对象,并存入spring容器)
静态工厂类
public class StaticFactory {
public static IAccountService getAccountService() {
return new AccountServiceImpl();
}
}
配置方式
<bean id = "accountService" class =
"com.itheima.factory.StaticFactory" factory-method="getAccountService"></bean>
这种方法是使用StaticFactory的静态方法的getAccountService创建对象,并存入spring容器。
factory-method:指定生产对象的静态方法。
依赖注入
依赖注入的概念
依赖注入(Dependency Injection)是spring框架核心ioc的具体实现.
通过控制反转,我们把创建对象的创建交给了spring,由于代码中不可能消除所有依赖,例如:
业务层仍然会调用持久层的方法,因此业务层类中应包含持久化层的实现类对象.也就是我们只要等框架通过配置的方式将持久层对象传入业务层就可以。
依赖注入的方法
一 使用构造函数注入
注意,赋值的操作不是我们做的,而是通过配置的方式让spring框架为我们注入。
账户的业务层实现类
public class AccountServiceImpl implements IAccountService {
private String name;
private Integer age;
private Date birthday;
public AccountServiceImpl(String name, Integer age, Date birthday) {
this.name = name;
this.age = age;
this.birthday = birthday;
}
public void saveAccount(){
System.out.println("service中的saveAccount方法执行了。。。"+name+","+age+","+birthday);
}
}
配置文件
<bean id="accountService" class="com.itheima.service.impl.AccountServiceImpl">
<constructor-arg name="name" value="辉哥"></constructor-arg>
<constructor-arg name="age" value="18"></constructor-arg>
<constructor-arg name="birthday" ref="now"></constructor-arg>
</bean>
<!-- 使用Date类的无参构造函数创建Date对象 -->
<bean id="now" class="java.util.Date"></bean>
涉及的标签: <constructor-arg>
用来定义构造函数的参数。
bean标签体个人理解:
`<bean id="now" class="java.util.Date"></bean>
这个标签体的含义是读取class的全限定类名,
反射创建一个对象并且存入的核心容器中并使用,
比如我们可以用ref=“id”的这个方式把id里对应的对象取出来
二 使用set方法注入(常用)
在类中提供需要注入成员的set方法,创建对象只调用要赋值属性的set方法.
账户的业务层实现类
public class AccountServiceImpl2 implements IAccountService {
private String name;
private Integer age;
private Date birthday;
public void setName(String name) {
this.name = name;
}
public void setAge(Integer age) {
this.age = age;
}
public void setBirthday(Date birthday) {
this.birthday = birthday;
}
public void saveAccount(){
System.out.println(name+","+age+","+birthday);
}
}
配置文件
<!--set方法注入-->
<bean id="accountService2" class="com.itheima.service.impl.AccountServiceImpl2">
<property name="name" value="吕明辉"></property>
<property name="age" value="20"></property>
<property name="birthday" ref="now"></property>
</bean>
涉及的标签: ,用来定义要调用set方法的成员. 其主要属性:
- name:找的是类中setXxx方法的xxx部分
- value: 给基本数据类型和String类型赋值
- ref: 给其它Bean类型的字段赋值,ref属性的值应为配置文件中配置的Bean的id
注入集合字段
集合字段及其对应的标签按照集合的结构分为两类: 相同结构的集合标签之间可以互相替换.
-
只有键的结构:
数组字段: 标签表示集合,标签表示集合内的成员.
List字段: 标签表示集合,标签表示集合内的成员.
Set字段: 标签表示集合,标签表示集合内的成员.
其中,,标签之间可以互相替换使用. -
键值对的结构:
Map字段:
public class AccountServiceImpl3 implements IAccountService {
private String[] myStrs;
private List<String> myList;
private Set<String> mySet;
private Map<String,String> myMap;
private Properties myprops;
public void setMyStrs(String[] myStrs) {
this.myStrs = myStrs;
}
public void setMyList(List<String> myList) {
this.myList = myList;
}
public void setMySet(Set<String> mySet) {
this.mySet = mySet;
}
public void setMyMap(Map<String, String> myMap) {
this.myMap = myMap;
}
public void setMyprops(Properties myprops) {
this.myprops = myprops;
}
public void saveAccount(){
System.out.println(Arrays.toString(myStrs));
System.out.println(myList);
System.out.println(myMap);
System.out.println(mySet);
System.out.println(myprops);
}
}
<!--复杂/集合类型的注入-->
<bean id="accountService3" class="com.itheima.service.impl.AccountServiceImpl3">
<property name="myStrs">
<array>
<value>ss</value>
<value>s1</value>
<value>ss3</value>
</array>
</property>
<property name="myList">
<list>
<value>ss</value>
<value>s1</value>
<value>ss3</value>
</list>
</property>
<property name="mySet">
<set>
<value>ss</value>
<value>s1</value>
<value>ss3</value>
</set>
</property>
<property name="myMap">
<map>
<entry key="a" value="21"></entry>
<entry key="3a" value="221"></entry>
</map>
</property>
<property name="myprops">
<props>
<prop key="asdasd">aaa</prop>
</props>
</property>
</bean>