Spring--Bean管理与注入
- Spring Bean管理
- Spring 构成
- Bean管理
- pom.xml配置
- Spring注入
- IOC与DI
- set注入
- 构造方法注入
- set注入还是构造方法注入
- 自动注入
Spring Bean管理
Bean生命周期:
四个阶段:
1、实例化 CreateBeanInstance
是指Spring通过反射获取Bean的构造方法进行实例化的过程
2、属性赋值 PopulateBean3、初始化 Initialization
是指Bean的属性赋值、执行初始化方法(init-method)的过程
4、销毁 Destruction
Spring 构成
Bean管理
创建applicationContext.xml
配置被管理的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
https://www.springframework.org/schema/beans/spring-beans.xsd">
<!-- <bean id="userDao" class="com.hisoft.dao.impl.UserDaoImpl"></bean>-->
<bean name="userDao" class="com.hisoft.dao.impl.UserDaoImpl" init-method="init" scope="singleton" destroy-method="destroy"></bean>
<bean class="com.hisoft.dao.impl.UserDaoImpl" init-method="init"></bean>
<bean class="com.hisoft.dao.impl.UserDaoImpl" lazy-init="true"></bean><!--懒加载-->
</beans>
获取Bean
import com.hisoft.dao.impl.UserDaoImpl;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class SpringTest {
public static void main(String[] args) {
//常规
// UserDaoImpl userDao = new UserDaoImpl();
// userDao.save();
//Bean 管理 构建spring容器实例 交给spring容器管理
//spring容器启动时,会将所有的bean实例化
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
UserDaoImpl userDao1 = (UserDaoImpl) context.getBean("userDao");
userDao1.save();
UserDaoImpl bean = (UserDaoImpl) context.getBean("com.hisoft.dao.impl.UserDaoImpl#1");
bean.save();
}
}
pom.xml配置
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.hisoft</groupId>
<artifactId>spring</artifactId>
<version>1.0-SNAPSHOT</version>
<dependencies>
<!-- https://mvnrepository.com/artifact/org.springframework/spring-beans -->
<!--spring beans-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
<version>5.2.9.RELEASE</version>
</dependency>
<!--spring core-->
<!-- https://mvnrepository.com/artifact/org.springframework/spring-core -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>5.2.9.RELEASE</version>
</dependency>
<!--spring context-->
<!-- https://mvnrepository.com/artifact/org.springframework/spring-context -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.2.9.RELEASE</version>
</dependency>
</dependencies>
</project>
Spring注入
IOC与DI
IOC (Inverse of Control) 控制翻转,把对象创建交给spring进行配置;
DI (Dependency Injection) 依赖注入,向类里面的属性中设置值;
关系:依赖注入不能单独存在,需要在ioc的基础之上完成操作。
注入的方式:set注入与构造方法注入
set注入
配置xml
<bean id="userService" class="com.hisoft.service.UserServiceImpl">
<!--局部注入userDao name的值为set后面的name-->
<property name="userDao" ref="userDao"/>
<!--局部注入 作用域小-->
<!--<property name="userDao">
<bean class="com.hisoft.dao.impl.UserDaoImpl"/>
</property>-->
<property name="name" value="Rose"/>
<property name="age" value="12"/>
<property name="list">
<list>
<value>Jerry</value>
<value>Tom</value>
<value>Mary</value>
</list>
</property>
<property name="map">
<map>
<entry key="A" value="a"></entry>
<entry key="B" value="b"></entry>
<entry key="C" value="c"></entry>
</map>
</property>
<property name="properties">
<props>
<prop key="R">r</prop>
<prop key="T">t</prop>
</props>
</property>
</bean>
<bean id="userDao" class="com.hisoft.dao.impl.UserDaoImpl"/> <!--id与name都可-->
UserDaoImpl
//面向接口编程:解耦 降低耦合度
public class UserDaoImpl implements UserDao {
public UserDaoImpl(){
System.out.println("create.....");
}
public void save(){
System.out.println("save....");
}
}
类UserServiceImpl
//DI 依赖注入
public class UserServiceImpl {
private UserDao userDao;
public String name;
public Integer age;
public List<String> list;
public Map<String,Object> map;
public Properties properties;
public void save(){
userDao.save();
}
public void setUserDao(UserDao userDao) {
this.userDao = userDao;
}
public void setName(String name) {
this.name = name;
}
public void setAge(Integer age) {
this.age = age;
}
public void setList(List<String> list) {
this.list = list;
}
public void setMap(Map<String, Object> map) {
this.map = map;
}
public void setProperties(Properties properties) {
this.properties = properties;
}
}
类UserServiceTest
import com.hisoft.service.UserServiceImpl;
import org.springframework.context.support.AbstractApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class UserServiceTest {
public static void main(String[] args) {
// UserServiceImpl userService = new UserServiceImpl();
// userService.save();
AbstractApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
UserServiceImpl userService = (UserServiceImpl) context.getBean("userService");
userService.save();
System.out.println(userService.name); //Rose
System.out.println(userService.age); //12
System.out.println(userService.list); //[Jerry, Tom, Mary]
System.out.println(userService.map); //{A=a, B=b, C=c}
System.out.println(userService.properties); //{T=t, R=r}
}
}
构造方法注入
xml配置 (四种)
<bean id="bookDao" class="com.hisoft.dao.impl.BookDaoImpl"/>
<bean id="bookService" class="com.hisoft.service.BookServiceImpl">
<constructor-arg type="com.hisoft.dao.BookDao" ref="bookDao"/>
<constructor-arg type="java.lang.String" value="Alex"/>
<constructor-arg type="java.lang.String" value="Shanghai"/>
<constructor-arg type="java.util.List" value="list"/>
<constructor-arg name="bookDao" ref="bookDao"/>
<constructor-arg name="name" value="Rose"/>
<constructor-arg name="address" value="Beijing"/>
<constructor-arg name="list" value="list"/>
<constructor-arg index="0" ref="bookDao"/>
<constructor-arg index="1" value="Alex"/>
<constructor-arg index="2" value="Shanghai"/>
<constructor-arg index="3">
<list>
<value>Rose</value>
<value>Alex</value>
</list>
</constructor-arg>
<constructor-arg ref="bookDao"/>
<constructor-arg value="Mary"/>
<constructor-arg value="Beijing"/>
<constructor-arg>
<list>
<value>Rose</value>
<value>Alex</value>
</list>
</constructor-arg>
</bean>
BookServiceImpl:
public class BookServiceImpl {
private BookDao bookDao;
public BookServiceImpl(BookDao bookDao, String name, String address,List<String> list){
System.out.println("name:" + name);
System.out.println("address:" + address);
System.out.println(list);
this.bookDao = bookDao;
}
public void save(){
bookDao.save();
}
}
BookServiceTest
public class BookServiceTest {
public static void main(String[] args) {
AbstractApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
BookServiceImpl bookService = (BookServiceImpl) context.getBean("bookService");
bookService.save();
}
}
set注入还是构造方法注入
使用构造方法注入的理由:
• 构造方法注入使用强依赖规定,如果不给足够的参数,对象则无法创建。
• 由于Bean 的依赖都通过构造方法设置了,那么就不用写更多的 set 方法,有助于减少代码量。使用 set 注入的理由:
• 如果Bean有很多的依赖,那么构造方法的参数列表会变的很长。
• 如果一个对象有多种构造方法,构造方法会造成代码量增加。
• 如果构造方法中有两个以上的参数类型相同,那么将很难确定参数的用途。
自动注入
autowire的值:
• no 默认值,不进行自动注入
• byName 根据需要注入的属性名在容器内寻找名称相同的Bean,如果找到就注入,找不到就不注入
• byType 根据需要注入的属性类型在容器找类型相同的Bean,如果找到就注入,找不到就不注入,如果找到多个 类型相同的Bean,则抛出异常
• constructor 注入先根据byName,如果找不到再根据byType找
配置xml: (依赖于set方法和构造方法)
<!--default-autowire="constructor" 全局自动注入-->
<bean id="newsDao" class="com.hisoft.dao.impl.NewsDaoImpl"/>
<!-- <bean id="newsService" class="com.hisoft.service.NewsServiceImpl"/>-->
<bean id="newsService" class="com.hisoft.service.NewsServiceImpl" autowire="constructor"/>
<!-- <bean id="newsService" class="com.hisoft.service.NewsServiceImpl" autowire="byType"/>-->