Spring核心容器
一、Spring简介
Spring是一个轻量级控制反转(IoC)和面向切面(AOP)的容器框架。Spring的用途不仅仅限于服务器端的开发。从简单性、可测试性和松耦合性角度而言,绝大部分Java应用都可以从Spring中受益。
二、CoreContainer核心容器入门
1、CoreContainer核心容器
IoC:使用IoC容器管理bean,控制反转(实现解耦)
DI:在IoC容器内将有依赖关系的bean进行关系绑定。依赖注入
Bean:IoC管理的bean
2、IoC入门
导入spring到pom文件
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.2.10.RELEASE</version>
</dependency>
在applicationContext.xml中配置bean
<!--bean标签标示配置bean,id属性标示给bean起名字,class属性表示给bean定义类型-->
<bean id="bookDao" class="com.lijun.dao.impl.BookDaoImpl"/>
获取IoC容器、获取bean(根据bean配置id获取)
ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
BookDao bookDao = (BookDao) ctx.getBean("bookDao");
3、DI入门
删除业务层中使用new的方式创建的dao对象,提供对应的set方法。
public class BookServiceImpl implements BookService {
private BookDao bookDao;
public void save() {
bookDao.save();
}
public void setBookDao(BookDao bookDao) {
this.bookDao = bookDao;
}
}
配置server与dao的关系
<bean id="bookService" class="com.lijun.service.impl.BookServiceImpl">
<!--property标签表示配置当前bean的属性
name属性表示配置哪一个具体的属性
ref属性表示参照哪一个bean-->
<property name="bookDao" ref="bookDao"/>
</bean>
4、Bean基础配置
scope:设置bean创建的对象是否是单例,singleton默认为单例,prototype为非单例
lazy-init:设置bean对象是否延时加载
init-method:设置bean初始化生命周期回调函数
destroy-method:设置bean销毁生命周期回调函数,仅适用于单例对象
<bean id="bookDao" class="com.lijun.dao.impl.BookDaoImpl"
scope="singleton"
lazy-init="true"
init-method="init"
destroy-method="destory"/>
类中设置生命周期方法
public class BookDaoImpl implements BookDao {
public void save() {
}
//表示bean初始化对应的操作
public void init(){
}
//表示bean销毁前对应的操作
public void destory(){
}
}
接口设置生命周期方法
public class BookServiceImpl implements BookService, InitializingBean, DisposableBean {
private BookDao bookDao;
public void setBookDao(BookDao bookDao) {
this.bookDao = bookDao;
}
public void save() {
bookDao.save();
}
public void destroy() throws Exception {
System.out.println("service destroy");
}
public void afterPropertiesSet() throws Exception {
System.out.println("service init");
}
}
5、Bean实例化
构造方法实例化bean
<bean id="bookDao" class="com.lijun.dao.impl.BookDaoImpl"/>
静态工厂实例化bean
public class BookDaoFactory {
public static BookDao getBookDao(){
return new BookDaoImpl();
}
}
<bean id="bookDao" class="com.lijun.factory.BookDaoFactory " factory-method="getBookDao"/>
实例工厂实例化bean
public class BookDaoFactory {
public BookDao getBookDao(){
return new BookDaoImpl();
}
}
<bean id="bookDao" class="com.lijun.factory.BookDaoFactory "/>
FactoryBean实例化bean
public class BookDaoFactoryBean implements FactoryBean<BookDao> {
//代替原始实例工厂中创建对象的方法
public BookDao getObject() throws Exception {
return new BookDaoImpl();
}
public Class<?> getObjectType() {
return BookDao.class;
}
}
<bean id="bookDao" class="com.lijun.factory.BookDaoFactoryBean"/>
三、依赖注入
1、setter注入
- 简单类型
public class BookDaoImpl implements BookDao {
private String databaseName;
private int connectionNum;
//setter注入需要提供要注入对象的set方法
public void setConnectionNum(int connectionNum) {
this.connectionNum = connectionNum;
}
//setter注入需要提供要注入对象的set方法
public void setDatabaseName(String databaseName) {
this.databaseName = databaseName;
}
public void save() {
System.out.println("book dao save ..."+databaseName+","+connectionNum);
}
}
<!--注入简单类型-->
<bean id="bookDao" class="com.lijun.dao.impl.BookDaoImpl">
<!--property标签:设置注入属性-->
<!--name属性:设置注入的属性名,实际是set方法对应的名称-->
<!--value属性:设置注入简单类型数据值-->
<property name="connectionNum" value="100"/>
<property name="databaseName" value="mysql"/>
</bean>
- 引用类型
public class BookServiceImpl implements BookService{
private BookDao bookDao;
private UserDao userDao;
//setter注入需要提供要注入对象的set方法
public void setUserDao(UserDao userDao) {
this.userDao = userDao;
}
//setter注入需要提供要注入对象的set方法
public void setBookDao(BookDao bookDao) {
this.bookDao = bookDao;
}
public void save() {
bookDao.save();
userDao.save();
}
}
<bean id="userDao" class="com.lijun.dao.impl.UserDaoImpl"/>
<!--注入引用类型-->
<bean id="bookService" class="com.lijun.service.impl.BookServiceImpl">
<!--property标签:设置注入属性-->
<!--name属性:设置注入的属性名,实际是set方法对应的名称-->
<!--ref属性:设置注入引用类型bean的id或name-->
<property name="bookDao" ref="bookDao"/>
<property name="userDao" ref="userDao"/>
</bean>
2、构造器注入
- 简单类型
public class BookDaoImpl implements BookDao {
private String databaseName;
private int connectionNum;
public BookDaoImpl(String databaseName, int connectionNum) {
this.databaseName = databaseName;
this.connectionNum = connectionNum;
}
public void save() {
System.out.println("book dao save ..."+databaseName+","+connectionNum);
}
}
<bean id="bookDao" class="com.lijun.dao.impl.BookDaoImpl">
<!--根据构造方法参数位置注入-->
<constructor-arg index="0" value="mysql"/>
<constructor-arg index="1" value="100"/>
</bean>
- 引用类型
public class BookServiceImpl implements BookService{
private BookDao bookDao;
private UserDao userDao;
public BookServiceImpl(BookDao bookDao, UserDao userDao) {
this.bookDao = bookDao;
this.userDao = userDao;
}
public void save() {
bookDao.save();
userDao.save();
}
}
<bean id="userDao" class="com.lijun.dao.impl.UserDaoImpl"/>
<bean id="bookService" class="com.lijun.service.impl.BookServiceImpl">
<constructor-arg name="userDao" ref="userDao"/>
<constructor-arg name="bookDao" ref="bookDao"/>
</bean>
3、自动装配
public class BookServiceImpl implements BookService{
private BookDao bookDao;
public void setBookDao(BookDao bookDao) {
this.bookDao = bookDao;
}
public void save() {
bookDao.save();
}
}
<bean class="com.lijun.dao.impl.BookDaoImpl"/>
<!--autowire属性:开启自动装配,通常使用按类型装配-->
<bean id="bookService" class="com.lijun.service.impl.BookServiceImpl" autowire="byType"/>
4、集合注入
public class BookDaoImpl implements BookDao {
private int[] array;
private List<String> list;
private Set<String> set;
private Map<String,String> map;
private Properties properties;
public void setArray(int[] array) {
this.array = array;
}
public void setList(List<String> list) {
this.list = list;
}
public void setSet(Set<String> set) {
this.set = set;
}
public void setMap(Map<String, String> map) {
this.map = map;
}
public void setProperties(Properties properties) {
this.properties = properties;
}
public void save() {
System.out.println("book dao save ...");
System.out.println("遍历数组:" + Arrays.toString(array));
System.out.println("遍历List" + list);
System.out.println("遍历Set" + set);
System.out.println("遍历Map" + map);
System.out.println("遍历Properties" + properties);
}
}
注入集合数据源
<bean id="bookDao" class="com.lijun.dao.impl.BookDaoImpl">
<!--数组注入-->
<property name="array">
<array>
<value>100</value>
<value>200</value>
<value>300</value>
</array>
</property>
<!--list集合注入-->
<property name="list">
<list>
<value>itcast</value>
<value>itlijun</value>
<value>boxuegu</value>
<value>chuanzhihui</value>
</list>
</property>
<!--set集合注入-->
<property name="set">
<set>
<value>itcast</value>
<value>itlijun</value>
<value>boxuegu</value>
<value>boxuegu</value>
</set>
</property>
<!--map集合注入-->
<property name="map">
<map>
<entry key="country" value="china"/>
<entry key="province" value="henan"/>
<entry key="city" value="kaifeng"/>
</map>
</property>
<!--Properties注入-->
<property name="properties">
<props>
<prop key="country">china</prop>
<prop key="province">henan</prop>
<prop key="city">kaifeng</prop>
</props>
</property>
</bean>
5、数据源对象管理
pom中引入druid、mysql
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.1.16</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.47</version>
</dependency>
在applicationContext.xml中配置bean
<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/spring_db"/>
<property name="username" value="root"/>
<property name="password" value="root"/>
</bean>
获取dataSource对象
ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
DataSource dataSource = (DataSource) ctx.getBean("dataSource");
System.out.println(dataSource);
加载properties文件
<?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
http://www.springframework.org/schema/context/spring-context.xsd
">
<!--system-properties-mode属性:是否加载系统属性-->
<!--classpath*:*.properties : 设置加载当前工程类路径和当前工程所依赖的所有jar包中的所有properties文件-->
<context:property-placeholder location="classpath*:*.properties" system-properties-mode="NEVER"/>
<!--使用属性占位符${}读取properties文件中的属性-->
<!--说明:idea自动识别${}加载的属性值,需要手工点击才可以查阅原始书写格式-->
<bean class="com.alibaba.druid.pool.DruidDataSource">
<property name="driverClassName" value="${jdbc.driver}"/>
<property name="url" value="${jdbc.url}"/>
<property name="username" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
</bean>
<bean id="bookDao" class="com.lijun.dao.impl.BookDaoImpl">
<property name="name" value="${username}"/>
</bean>
</beans>
四、Spring注解开发
@Component:设置bean对象注解
@Component("bookDao"):设置bean对象注解,设置id名称
<context:component-scan base-package="com.lijun"/>:设置扫描包中的bean对象
衍生注解:
- @Service:设置业务层bean
- @Controller:设置表现层bean
- @Repository("bookDao"):设置数据层bean
1、配置类代替配置文件
//声明当前类为Spring配置类
@Configuration
//设置bean扫描路径,多个路径书写为字符串数组格式
@ComponentScan({"com.lijun.service","com.lijun.dao"})
public class SpringConfig {
}
//获取配置类中的bean
ApplicationContext ctx = new AnnotationConfigApplicationContext(SpringConfig.class);
BookDao bookDao = (BookDao) ctx.getBean("bookDao");
System.out.println(bookDao);
2、设置bean作用范围、生命周期
@Repository
@Scope("singleton")//设置为单例
public class BookDaoImpl implements BookDao {
public void save() {
System.out.println("book dao save ...");
}
//@PostConstruct设置bean的初始化方法
@PostConstruct
public void init() {
System.out.println("init ...");
}
//@PreDestroy设置bean的销毁方法
@PreDestroy
public void destroy() {
System.out.println("destroy ...");
}
}
3、自动装配模式
注入引用类型
@Service
public class BookServiceImpl implements BookService {
//@Autowired:注入引用类型,自动装配模式,默认按类型装配
@Autowired
//@Qualifier:自动装配bean时按bean名称装配
@Qualifier("bookDao")
private BookDao bookDao;
public void save() {
System.out.println("book service save ...");
bookDao.save();
}
}
注入简单类型
@Repository("bookDao")
public class BookDaoImpl implements BookDao {
//@Value:注入简单类型(无需提供set方法)
@Value("${name}")
private String name;
public void save() {
System.out.println("book dao save ..." + name);
}
}
4、配置类加载properties配置文件
@Configuration
@ComponentScan("com.lijun")
@PropertySource({"jdbc.properties"})
public class SpringConfig {
}
5、管理DataSource的bean
设置jdbc.properties参数值
jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/spring_db?useSSL=false
jdbc.username=root
jdbc.password=root
读取jdbc参数
public class JdbcConfig {
@Value("${jdbc.driver}")
private String driver;
@Value("${jdbc.url}")
private String url;
@Value("${jdbc.username}")
private String userName;
@Value("${jdbc.password}")
private String password;
@Bean
public DataSource dataSource(){
DruidDataSource ds = new DruidDataSource();
ds.setDriverClassName(driver);
ds.setUrl(url);
ds.setUsername(userName);
ds.setPassword(password);
return ds;
}
}
加载jdbc.properties、JdbcConfig.class
@Configuration
//@PropertySource:加载类路径jdbc.properties文件
@PropertySource("classpath:jdbc.properties")
@Import({JdbcConfig.class})
public class SpringConfig {
}