spring核心容器

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呢?

  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属性 为 prorotype4

<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的三种方式
  1. 构造方法(常用) 如果无参构造方法不存在则抛出异常 BeanCreationException

  2. 静态工厂 (了解) 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的生命周期

  • 初始化容器
    1. 创建对象(内存分配)
    2. 执行构造方法
    3. 执行属性注入(set操作)
    4. 执行bean初始化方法
  • 使用bean
    1. 执行业务操作
  • 关闭/销毁容器
    1. 执行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)
  1. 引入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>
    
  2. 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);
        }
    }
    
  3. 运行效果

{
	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加载数据源
  1. 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>
  1. 配置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>
    
  2. 运行效果

    四月 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>

配置properties

9.容器
1.创建容器
  1. 加载类路径下的配置文件
ApplicationContext ctx = new ClassPathXmlAppliactionContext("applicationContext.xml");
  1. 加载文件系统下的配置文件(绝对路径)
Application ctx = new FileSystemApplicationContext("D:\java_code\springdemo1\src\main\resources\applicationContext.xml");
  1. 加载多个配置文件
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的区别

  1. BeanFactory不支持占位符,<property name="url" value="${jdbc.url}"></property>无效

  2. BeanFactory加载bean的时机不同:延迟加载bean

  3. ApplicationContext:立即加载bean,即立即加载构造方法,如要延迟加载可配置

    <bean id="bookDao" class="com.ttc.dao.impl.BookDaoImpl" lazy-init="true"></bean>
    

bean的常用属性

完结撒花🌺


  1. 通过setter方法传入一个对象 ↩︎

  2. bookDao的别名是lisi ↩︎

  3. 当前创造的bean是单例还是非单例 ↩︎

  4. 原型 ↩︎

  5. 对实例工厂实例化bean的改良 ↩︎

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值