spring核心容器总结
1.IoC入门
1.maven坐标导入
<?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.ttc</groupId>
<artifactId>springdemo1</artifactId>
<version>1.0-SNAPSHOT</version>
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.2.10.RELEASE</version>
</dependency>
</dependencies>
</project>
2.创建dao和service
1.创建dao层接口和其实现类
BookDao接口
package com.ttc.dao;
public interface BookDao{
void save();
}
BookDaoImpl实现类
package com.ttc.dao.impl;
import com.ttc.dao.BookDao;
public class BookDaoImpl implements BookDao{
public void save(){
System.out.println("BookDao save!");
}
}
2.创建service层接口和其实现类
BookService接口
package com.ttc.service;
public interface BookService{
void save();
}
BookServiceImpl实现类
package com.ttc.service.impl;
import com.ttc.dao.BookDao;
import com.ttc.dao.impl.BookDaoImpl;
import com.ttc.service.BookService;
public class BookServiceImpl implements BookService {
private BookDao bookDao = new BookDaoImpl();
public void save(){
System.out.println("BookService save!");
bookDao.save();
}
}
3.配置applicationContext.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">
<!--1.id是一个bean的名字,用来唯一标识一个bean-->
<!--2.class是一个bean所在的具体位置,写实现类,不写接口-->
<bean id="bookDao" class="com.ttc.dao.impl.BookDaoImpl"/>
<bean id="bookService" class="com.ttc.service.impl.BookServiceImpl"/>
</beans>
4.创建IoC容器并获取bean
package com.ttc;
import com.ttc.dao.BookDao;
import com.ttc.service.BookService;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class Application{
public static void main(String[] args){
// 创建IoC容器
ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
// 获取bean
BookDao bookDao = (BookDao) ctx.getBean("bookDao");
bookDao.save();
BookService bookService = (BookService) ctx.getBean("bookService");
bookService.save();
}
}
2.DI入门
基于IoC管理bean
Service中不再使用new形式获取Dao对象
配置Service和Dao之间的关系
BookServiceImpl实现类
不再使用new 的方式获取bookDao对象
如何给bookDao这个属性赋值1呢?
- 不妨利用
setter方法
给其传入对象
package com.ttc.service.impl;
import com.ttc.dao.BookDao;
import com.ttc.service.BookService;
public class BookServiceImpl implements BookService {
private BookDao bookDao;
public void save(){
System.out.println("BookService save!");
bookDao.save();
}
public void setBookDao(BookDao bookDao){
this.bookDao=booKDao;
}
}
1.配置Service和Dao之间的关系
<?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">
<!--1.id是一个bean的名字,用来唯一标识一个bean-->
<!--2.class是一个bean所在的具体位置,写实现类,不写接口-->
<bean id="bookDao" class="com.ttc.dao.impl.BookDaoImpl"/>
<bean id="bookService" class="com.ttc.service.impl.BookServiceImpl">
<!--配置service和dao之间的关系-->
<!--这里的ref表示引用bean,此处引用的是id="bookDao的bean"-->
<!--property标签标识配置当前bean的属性-->
<!--name属性表示配置(实体类)中的具体的属性-->
<!--ref属性表示参照哪一个bean-->
<property name="bookDao" ref="bookDao"></property>
</bean>
</beans>
TODO:如果不加
<property name="bookDao" ref="bookDao"></property>
则会出现:
java.lang.NullPointerException异常
3.bean配置
bean基本配置
bean别名配置
bean范围配置
<!--bean别名配置-->
<!-- name属性表示配置别名 可以有多个别名,彼此之间通过逗号 空格 分号 分割-->
<bean id="bookService" class="com.ttc.service.impl.BookServiceImpl" name="service;zhangsan"></bean>
/* java创建IoC并获取Bean
getBean方法可传:
1.别名 zhangsan或者service
2.id名称 bookService
3.BookService.class (java反射机制)
4.BookServiceImpl.class (java反射机制)
*/
ApplicationContext ctx = new ClassPathXmlApplicationConext("applicationContext.xml");
BookService bookService = (BookService) ctx.getBean("zhangsan")
bookService.save();
TODO:property的ref属性也可引用其他bean的别名2
<bean id="bookDao" class="com.ttc.dao.impl.BookDaoImpl" name="lisi"></bean>
<bean id="bookService" class="com.ttc.dao.impl.BookServiceImpl" name="service;zhangsan">
<property name="bookDao" ref="lisi"></property>
</bean>
ApplicationContext无论通过id还是name获取bean,如无法获取到,则抛出异常 NoSuchBeanDefinitionException
1.何为bean的作用范围3?
IoC容器创建bean 默认单例 singleton
BookDao bookDao1 = (BookDao) ctx.getBean("bookDao");
System.out.println(bookDao1);
BookDao bookDao2 = (BookDao) ctx.getBean("bookDao");
System.out.println(bookDao2);
设置非单例 修改bean的scope
属性 为 prorotype
4
<bean id="bookDao" class="com.ttc.dao.impl.BookDaoImpl" scope="prototype"></bean>
2.为什么bean默认为单例?
主要为了减少对象创建来提升性能
在spring中bean基本上都是通过反射
机制创建的,反射可以动态创建和使用对象,降低系统耦合,提高代码复用率Spring对象默认单例的优点:
- 减少创建对象的次数,降低反射低效率对框架整体性能的影响
- 对象创建的少了,GC自然减少,提高性能
- 更快速的获取bean,这个涉及到Spring的三级缓存,只有在第一次创建对象时才会去创建,其余的都是从第一级缓存直接获取,提高性能。
Spring对象默认单例的缺点:
- 会带来线程安全问题,有状态bean(能存储数据的bean)在单例模式下线程不安全。因此,Spring也提供了其他多种bean的作用域。
适合spring管理的bean:
- 表现层对象
- 业务层对象
- 数据层对象
- 工具对象
不适合交给spring容器管理的bean: 封装实体的域对象
4.bean的实例化
1.spring内部通过构造方法来创建对象
public class testDog {
public static void main(String[] args) {
Dog dog = new Dog();
dog.say();
}
}
class Dog {
public Dog(){
System.out.println("这是构造方法!!!");
}
public void say() {
System.out.println("汪汪汪");
}
}
// 运行结果为:
这是构造方法!!!
汪汪汪
如若将Dog类的构造方法 访问修饰符改为 private
则抛出异常:java: Dog() 在 Dog 中是 private 访问控制
<property name="bookDao" ref="bookDao"></property>
ApplicationContext在加载application.xml文件时会调用BookDao类的构造方法,哪怕没有getBean(“bookDao”)
但是在spring实例化bean时将构造方法访问修饰符改为private
,仍能实例化bean 通过反射机制
2.spring创建bean调用的是无参的构造方法
package com.ttc.dao.impl;
import com.ttc.dao.BookDao;
public class BookDaoImpl implements BookDao {
private BookDaoImpl(){
System.out.println("这是BookDaoImpl构造方法!");
}
public void save() {
System.out.println("BookDao save!");
}
}
3.实例化bean的三种方式
-
构造方法(常用) 如果无参构造方法不存在则抛出异常 BeanCreationException
-
静态工厂 (了解)
public static CatDao getCatDao(){return new CatDaoImpl();}
package com.ttc.factory; import com.ttc.dao.CatDao; import com.ttc.dao.impl.CatDaoImpl; public class CatDaoFactory { public static CatDao getCatDao() { return new CatDaoImpl(); } }
package com.ttc; import com.ttc.dao.CatDao; import com.ttc.factory.CatDaoFactory; public class Application { public static void main(String[] args) { // 静态工厂创建对象 CatDao catDao = CatDaoFactory.getCatDao(); catDao.save(); } }
<?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属性是实际造出来的对象类型--> <!--factory-method:工厂里面调用哪个方法去创建对象--> <bean id="catDao" class="com.ttc.factory.CatDaoFactory" factory-method="getCatDao"> </bean> </beans>
package com.ttc; import com.ttc.dao.CatDao; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; public class Application { public static void main(String[] args) { ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml"); CatDao catDao = (CatDao) ctx.getBean("catDao"); catDao.save(); } }
3.实例工厂(了解)
package com.ttc.factory;
import com.ttc.dao.DogDao;
import com.ttc.dao.impl.DogDaoImpl;
public class DogDaoFactory {
public DogDao getDogDao() {
return new DogDaoImpl();
}
}
package com.ttc;
import com.ttc.dao.DogDao;
import com.ttc.factory.DogDaoFactory;
public class Application {
public static void main(String[] args) {
// 实例工厂创建对象
DogDaoFactory dogDaoFactory = new DogDaoFactory();
DogDao dogDao = dogDaoFactory.getDogDao();
dogDao.save();
}
}
<?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-->
<!--1.先造工厂的实例对象bean即id="dogDaoFactory"-->
<!--2.dogDao中添加factory-bean="dogDaoFactory"-->
<bean id="dogDaoFactory" class="com.ttc.factory.DogDaoFactory"></bean>
<bean id="dogDao" class="com.ttc.factory.DogDaoFactory" factory-method="getDogDao" factory-bean="dogDaoFactory">
</bean>
</beans>
package com.ttc;
import com.ttc.dao.DogDao;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class Application {
public static void main(String[] args) {
ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
DogDao dogDao = (DogDao) ctx.getBean("dogDao");
dogDao.save();
}
}L
4.FactoryBean实例化bean5 (实用)
package com.ttc.factory;
import com.ttc.dao.DogDao;
import com.ttc.dao.impl.DogDaoImpl;
import org.springframework.beans.factory.FactoryBean;
public class DogDaoFactoryBean implements FactoryBean<DogDao> {
// 代替原始工厂,实现创建对象的方法
@Override
public DogDao getObject() throws Exception {
return new DogDaoImpl();
}
// 创建出的对象的类型
@Override
public Class<?> getObjectType() {
return DogDao.class;
}
// 是否单例 true为单例 false为非单例
@Override
public boolean isSingleton() {
return true;
}
}
<?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">
<!--使用FactoryBean改良实例工厂实例化对象-->
<bean id="dogDao" class="com.ttc.factory.DogDaoFactoryBean">
</bean>
</beans>
5.bean的生命周期
bean生命周期:bean从创建到销毁的整体过程
bean生命周期控制:在bean创建后到销毁前做的一些事情
1.bean中声明init-method和destroy-method属性
package com.ttc.dao;
import com.ttc.dao.BookDao;
public class BookDaoImpl implements BookDao{
public void save(){
System.out.println("BookDao save!");
}
// 表示bean初始化对应的操作
public void init(){
System.out.println("init...")
}
// 表示bean销毁前对应的操作
public void destroy(){
System.out.println("destroy...")
}
}
<?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">
<!--init-method属性:初始化执行方法-->
<!--destory-method属性:销毁前执行方法-->
<bean id="bookDao" class="com.ttc.dao.impl.BookDaoImpl" init-method="init" destroy-method="destroy">
</bean>
</beans>
注:为什么配置完init和destroy方法并在bean中指出后,发现只有init方法执行了,但destroty方法并没有执行?
因为我们写的程序运行在jvm上,jvm启动,IoC容器加载,初始化bean,执行完方法,退出jvm,并没有给bean销毁的机会
package com.ttc;
import com.ttc.dao.BookDao;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class Application{
public static void main(String[] args){
ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
BookDao bookDao =(BookDao) ctx.getBean("bookDao");
bookDao.save();
}
}
在ApplicationContext
接口中并没有 ctx.close
方法, 固不能直接关闭ctx,让bean销毁
需要用其实现类ClassPathXmlApplicationContext的close方法
ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
ctx.close();
ctx.close()
直接比较暴力,直接关闭IoC容器
建议注册关闭钩子ctx.registerShutdownHook();
ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
ctx.registerShutdownHook();
2.implemets初始化和销毁接口
package com.ttc.service.impl;
import com.ttc.dao.BookDao;
import com.ttc.service.BookService;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.InitializingBean;
public class BookServiceImpl implements BookService, InitializingBean, DisposableBean {
private BookDao bookDao;
public void save() {
System.out.println("BookService save!");
bookDao.save();
}
public void setBookDao(BookDao bookDao) {
System.out.println("初始化属性")
this.bookDao = bookDao;
}
@Override
public void destroy() throws Exception {
System.out.println("service销毁");
}
@Override
public void afterPropertiesSet() throws Exception {
System.out.println("service初始化");
}
}
afterPropertiesSet()
在属性完成初始化之后再执行
bean的生命周期
- 初始化容器
- 创建对象(内存分配)
- 执行构造方法
- 执行属性注入(set操作)
- 执行bean初始化方法
- 使用bean
- 执行业务操作
- 关闭/销毁容器
- 执行bean销毁方法
- 手动关闭容器 ClassPathXmlApplicationContext.close()
- 注册关闭钩子 ClassPathXmlApplicationContext.registerShutdownHook()
6.依赖注入方式
- 思考:向一个类中传递数据有几种方式?
- set方法(setter注入)
- 构造方法(构造器注入)
- 向bean中会注入哪些数据类型
- 简单类型
- 引用类型
1.setter注入引用类型
public class BookServiceImpl implements BookService{
private BookDao bookDao;
public void setBookDao(BookDao bookDao){
this.bookDao = bookDao;
}
}
<bean id="bookDao" class="com.ttc.dao.impl.BookDaoImpl"></bean>
<bean id="bookService" class="com.ttc.service.impl.BookServiceImpl">
<property name="bookDao" ref="bookDao"></property>
</bean>
2.setter注入简单类型
package com.ttc.service.impl;
import com.ttc.service.BookService;
public class BookServiceImpl implements BookService{
private int connectNum;
private String databaseName;
public void setConnectNum(int connectNum){
this.connectNum = connectNum;
}
public void setDatabaseName(String databaseName){
this.databaseName = databaseName;
}
public void save(){
System.out.println("bookService save " + connectNum + databaseName);
}
}
<?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="bookService" class="com.ttc.service.impl.BookServiceImpl">
<property name="connectNum" value="5"></property>
<property name="databaseName" value="druid"></property>
</bean>
</beans>
3.构造器注入引用类型
package com.ttc.service.impl;
import com.ttc.service.BookService;
import com.ttc.dao.BookDao;
public class BookServiceImpl implements BookService{
private BookDao bookDao;
public BookServiceImpl(BookDao bookDao){
this.bookDao = bookDao;
}
}
<?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="bookDao" class="com.ttc.dao.impl.BookDaoImpl"></bean>
<bean id="bookService" class="com.ttc.service.impl.BookServiceImpl">
<constructor-arg name="bookDao" ref="bookDao"></constructor-arg>
</bean>
</beans>
注:<constructor-arg/>
的name值指代构造方法中形参名
4.构造器注入简单类型
package com.ttc.service.impl;
import com.ttc.service.BookService;
public class BookServiceImpl implements BookService{
private int connectNum;
private String databaseName;
public BookServiceImpl(int connectNum,String databaseName){
this.connectNum = connectNum;
this.databaseName = databaseName;
}
@Override
public void save() {
System.out.println("bookService save " + connectNum + databaseName);
}
}
标准写法(耦合度高):
<?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="bookService" class="com.ttc.service.impl.BookServiceImpl">
<constructor-arg name="connectNum" value="66"></constructor-arg>
<constructor-arg name="databaseName" value="mysql"></constructor-arg>
</bean>
</beans>
其他写法:1.用type类型降低形参名的耦合(存在参数类型重复问题)
<?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="bookService" class="com.ttc.service.impl.BookServiceImpl">
<constructor-arg type="int" value="66"></constructor-arg>
<constructor-arg type="java.lang.String" value="mysql"></constructor-arg>
</bean>
</beans>
其他写法:2.用index标记降低耦合(解决参数类型重复)
<?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="bookService" class="com.ttc.service.impl.BookServiceImpl">
<constructor-arg index="0" value="66"></constructor-arg>
<constructor-arg index="1" value="mysql"></constructor-arg>
</bean>
</beans>
7.依赖自动装配
IoC容器根据bean所依赖的资源在容器中自动查找并注入到bean的过程称为自动装配 set方法需要提供
自动装配方式:
- 按类型(常用)
- 按名称
- 按构造方法
1.按类型自动装配
package com.ttc.service.impl;
import com.ttc.service.BookService;
import com.ttc.dao.BookDao;
public class BookServiceImpl implements BookService{
private BookDao bookDao;
public void setBookDao(BookDao bookDao){
this.bookDao = bookDao;
}
@Override
public void save(){
bookDao.save();
System.out.println("BookService save");
}
}
<?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="bookDao" class="com.ttc.dao.impl.BookDaoImpl"></bean>
<bean id="bookService" class="com.ttc.service.impl.BookServiceImpl" autowire="byType">
</bean>
</beans>
1.如没有待装配对象的set方法,则抛出异常:NullPointerException
2.如未声明待装配对象的bean,则抛出异常:NullPointerException
3.待装配对象的bean类型不唯一,则抛出异常:NoUniqueBeanDefinitionException
<bean id="bookDao1" class="com.ttc.dao.impl.BookDaoImpl"></bean>
<bean id="bookDao2" class="com.ttc.dao.impl.BookDaoImpl"></bean>
<bean id="bookService" class="com.ttc.service.impl.BookServiceImpl" autowire="byType"></bean>
4.autowire="byType"
待装配的bean不取id也能用
2.按名称装配
<?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="bookDao" class="com.ttc.dao.impl.BookDaoImpl"></bean>
<bean id="bookService" class="com.ttc.service.impl.BookServiceImpl" autowire="byName">
</bean>
</beans>
🤡:按名称装配
<bean id="bookDao" class="com.ttc.dao.impl.BookDaoImpl"/>
要和 bookService中Set方法名(SetBookDao)保持一致 否则抛出NullPointerException
自动装配特征:
- 用于引用类型,不能对简单类型进行操作
- byType装配时,必须保证相同类型的bean唯一
- byName装配时,变量名称与set方法名耦合,不推荐
- 自动装配优先级低于setter注入和构造器注入,同时出现时自动装配失效
8.集合注入
- 数组
- List
- Set
- Map
- Properties
1.注入集合属性
BookDao.java
package com.ttc.dao;
public interface BookDao{
public void save();
}
BookDaoImpl.java
package com.ttc.dao.impl;
import com.ttc.dao.BookDao;
import java.util.List;
import java.util.Set;
import java.util.Map;
import java.util.Properties;
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("BookDao save!");
System.out.println("1.遍历数组: " + Arrays.toString(array));
System.out.println("2.遍历list: " + list);
System.out.println("3.遍历set: " + set);
System.out.println("4.遍历map: " + map);
System.out.println("5.遍历properties: " + properties);
}
}
applicationContext.xml 放在/src/main/resources/ 目录下
<?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="bookDao" class="com.ttc.dao.impl.BookDaoImpl">
<property name="array">
<array>
<value>100</value>
<value>200</value>
<value>300</value>
</array>
</property>
<property name="list">
<list>
<value>dog</value>
<value>cat</value>
<value>animal</value>
</list>
</property>
<property name="set">
<set>
<value>dog2</value>
<value>cat2</value>
<value>animal2</value>
<value>animal2</value>
</set>
</property>
<property name="map">
<map>
<entry key="cat3" value="小猫"/>
<entry key="dog3" value="小狗"/>
<entry key="animal3" value="动物"/>
</map>
</property>
<property name="properties">
<props>
<prop key="username">zhangsan</prop>
<prop key="password">123456</prop>
</props>
</property>
</bean>
</beans>
Application.java
package com.ttc;
import com.ttc.dao.BookDao;
public class Application{
public static void main(String[] args){
ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
BookDao bookDao = (BookDao) ctx.getBean("bookDao");
bookDao.save();
}
}
运行效果:
D:\Java\jdk\bin\java.exe "-javaagent:D:\soft\IntelliJ IDEA
BookDao save!
1.遍历数组: [100, 200, 300]
2.遍历list: [cat, dog, animal]
3.遍历set: [cat2, dog2, animal2]
4.遍历map: {cat3=小猫, dog3=小狗, animal3=动物}
5.遍历properties: {password=123456, username=zhangsan}
Process finished with exit code 0
可以在集合属性中注入引用类型 <ref bean="beanId"/>
<property>
<array>
<value>100</value>
<value>200</value>
<value>300</value>
<ref bean="beanId"/>
</array>
</property>
2.数据源对象管理(第三方Bean)
-
引入druid坐标
<?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.ttc</groupId> <artifactId>springdemo1</artifactId> <version>1.0-SNAPSHOT</version> <packaging>war</packaging> <dependencies> <!--导入spring依赖--> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>5.2.10.RELEASE</version> </dependency> <!-- druid依赖 --> <dependency> <groupId>com.alibaba</groupId> <artifactId>druid</artifactId> <version>1.1.12</version> </dependency> <properties> <maven.compiler.source>8</maven.compiler.source> <maven.compiler.target>8</maven.compiler.target> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> </properties> </project>
-
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="dataSource" class="com.alibaba.druid.pool.DruidDataSource"> <property name="driverClassName" value="com.mysql.cj.jdbc.Driver"> </property> <property name="url" value="jdbc:mysql://localhost:3306/boot"></property> <property name="username" value="root"></property> <property naem="password" value="root"></property> </bean> </beans>
package com.ttc; import org.springframework.context.support.ClassPathXmlApplicationContext; import javax.sql.DataSource; public class Application { public static void main(String[] args) { ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml"); DataSource dataSource = (DataSource) ctx.getBean("dataSource"); System.out.println(dataSource); } }
-
运行效果
{
CreateTime:"2023-04-01 14:38:49",
ActiveCount:0,
PoolingCount:0,
CreateCount:0,
DestroyCount:0,
CloseCount:0,
ConnectCount:0,
Connections:[
]
}
Process finished with exit code 0
- 测试使用C3P0加载数据源
- maven依赖
<!-- https://mvnrepository.com/artifact/c3p0/c3p0 -->
<!--C3P0数据源-->
<dependency>
<groupId>c3p0</groupId>
<artifactId>c3p0</artifactId>
<version>0.9.1.2</version>
</dependency>
<!--jdbc驱动-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.28</version>
</dependency>
-
配置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="dataSource" class="com.alibaba.druid.pool.DruidDataSource"> <property name="driverClassName" value="com.mysql.cj.jdbc.Driver"> </property> <property name="url" value="jdbc:mysql://localhost:3306/boot"></property> <property name="username" value="root"></property> <property naem="password" value="root"></property> </bean> <bean id="dataSource2" class="com.mchange.v2.c3p0.ComboPooledDataSource"> <property name="driverClass" value="com.mysql.cj.jdbc.Driver"></property> <property name="jdbcUrl" value="jdbc:mysql://localhost:3306/boot"></property> <property name="user" value="root"></property> <property name="password" value="root"></property> </bean> </beans>
-
运行效果
四月 01, 2023 2:59:50 下午 com.mchange.v2.log.MLog <clinit> 信息: MLog clients using java 1.4+ standard logging. 四月 01, 2023 2:59:50 下午 com.mchange.v2.c3p0.C3P0Registry banner 信息: Initializing c3p0-0.9.1.2 [built 21-May-2007 15:04:56; debug? true; trace: 10] 四月 01, 2023 2:59:51 下午 com.mchange.v2.c3p0.impl.AbstractPoolBackedDataSource getPoolManager 信息: Initializing c3p0 pool... com.mchange.v2.c3p0.ComboPooledDataSource [ acquireIncrement -> 3, acquireRetryAttempts -> 30] Process finished with exit code 0
注:使用C3P0数据源需要导入mysql驱动,druid数据源无需
mysql驱动:
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.28</version>
</dependency>
3.加载properties文件
1.添加全新命名空间context
<?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">
</beans>
2.用context空间读取jdbc.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">
<!--context空间加载properties文件-->
<context:property-placeholder location="jdbc.properties"></context:property-placeholder>
<!--使用占位符${}读取properties里面的文件-->
<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
<property name="driverClassName" value="${jdbc.driver}"></property>
<property name="url" value="${jdbc.url}"></property>
<property name="username" value="${jdbc.username}"></property>
<property name="password" value="${jdbc.password}"></property>
</bean>
</beans>
3.创建jdbc.properties文件
jdbc.driver=com.mysql.cj.jdbc.driver
jdbc.url=jdbc:mysql://localhost:3306/boot
jdbc.username=root
jdbc.password=root
为防止系统属性和配置文件中的属性冲突在bean中配置用系统配置模式
<context:property-placeholder location="jdbc.properties" system-properties-mode="NEVER"></bean>
配置读取类路径里面的文件
<context:property-placeholder location="classpath:jdbc.properties"></context:property-placeholder>
读取所有路径中的文件
<context:property-placeholder location="classpath*:*.properties"></context:property-placeholder>
9.容器
1.创建容器
- 加载类路径下的配置文件
ApplicationContext ctx = new ClassPathXmlAppliactionContext("applicationContext.xml");
- 加载文件系统下的配置文件(绝对路径)
Application ctx = new FileSystemApplicationContext("D:\java_code\springdemo1\src\main\resources\applicationContext.xml");
- 加载多个配置文件
ApplicationContext ctx = new ClassPathXmlApplicationContext("bean1.xml","bean2.xml");
2.获取bean
// 方式一 根据bean的名称获取
BookDao bookDao = (BookDao) ctx.getBean("bookDao");
// 方式二 根据bean的名称并指定类型
BookDao bookDao = ctx.getBean("bookDao",BookDao.class);
// 方式三 根据bean的类型获取
BookDao bookDao = ctx.getBean(BookDao.class);
3.容器类层次结构
- 顶层接口 BeanFactory
- 常用接口 ApplicationContext
- 常用实现类 ClassPathXmlApplicationContext
- 提供关闭容器功能 ConfigurableApplicationContext接口
4.BeanFactory和ApplicationContext区别
package com.ttc;
import com.ttc.dao.BookDao;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.xml.XmlBeanFactory;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
import javax.sql.DataSource;
public class Application {
public static void main(String[] args) {
Resource resource = new ClassPathResource("applicationContext.xml");
BeanFactory factory = new XmlBeanFactory(resource);
BookDao bookDao = (BookDao) factory.getBean("bookDao");
bookDao.save();
}
}
BeanFactory和ApplicationContext的区别
-
BeanFactory不支持占位符,
<property name="url" value="${jdbc.url}"></property>
无效 -
BeanFactory加载bean的时机不同:延迟加载bean
-
ApplicationContext:立即加载bean,即立即加载构造方法,如要延迟加载可配置
<bean id="bookDao" class="com.ttc.dao.impl.BookDaoImpl" lazy-init="true"></bean>
完结撒花🌺