笔记参考雷神上课的印象笔记和源码
实验10:创建带有生命周期方法的bean 实验11:测试bean的后置处理器 实验12:引用外部属性文件★(spring管理连接池); 实验13:基于XML的自动装配(自定义类型自动赋值) javaBean(基本类型) (自定义类型的属性是一个对象,这个对象在容器中可能存在) 实验14:[SpEL测试I] 在SpEL中使用字面量、 引用其他bean、 引用其他bean的某个属性值、 调用非静态方法 调用静态方法、 使用运算符
实验10:创建带有生命周期方法的bean
<!-- 实验10:创建带有生命周期方法的bean
生命周期:bean的创建到销毁;
ioc容器中注册的bean;
1)、单例bean,容器启动的时候就会创建好,容器关闭也会销毁创建的bean
2)、多实例bean,获取的时候才创建;
我们可以为bean自定义一些生命周期方法;spring在创建或者销毁的时候就会调用指定的方法;
自定义初始化方法和销毁方法 init-method和destroy-method :The method must have no arguments,but may throw any exception
ConfigurableApplicationContext有close()方法
单例bean的生命周期
(容器启动)构造器-初始化方法-(容器关闭)销毁方法
多实例bean的生命周期
获取bean(构造器)-初始化方法- 容器关闭 不会调用bean的销毁方法
-->
<bean id="book01" class="com.atguigu.bean.Book"
destroy-method="myDestory" init-method="myInit" ></bean>
实验11:测试bean的后置处理器
<!--实验11:测试bean的后置处理器:BeanPostProcessor
Spring有一个接口:后置处理器:作用是可以在bean的初始化前后调用方法;
创建一个接口文件MyBeanPostProcessor.class 里面有两种方法
public Object postProcessBeforeInitialization(Object bean,String beanName){} 初始化之前调用
public Object postProcessAfterInitialization(Object bean,String beanName){} 初始化之后调用
Object bean
String beanName :bean在xml中配置的id
(容器启动)构造器-后置处理器before-初始化方法-后置处理器after-(容器关闭)销毁方法
无论bean是否有初始化方法,后置处理器都会默认其有,还会继续工作 比如car 就没有初始化方法
-->
<!--要想让MyBeanPostProcessor.class工作:1)编写后置处理器的实现类 2)将后置处理器注册在配置文件中-->
<bean id="beanPostProcessor" class="com.atguigu.bean.MyBeanPostProcessor"></bean>
<bean id="car01" class="com.atguigu.bean.Car"></bean>
实验12:引用外部属性文件★(spring管理连接池);
<?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-4.0.xsd">
<!--实验12:引用外部属性文件★依赖context名称空间 -->
<!-- 数据库连接池最好作为单实例;一个项目就一个连接池,连接池里面管理很多连接。连接是直接从连接池中拿 -->
<!-- 可以让Spring帮我们创建连接池对象,(管理连接池) -->
<!--<context:property-placeholder/> 加载外部配置文件 固定写法classpath:,表示引用类路径下的一个资源-->
<!--在IOCTest.class进行测试 1)从容器中拿到连接池 2)按照类型获取组件,可以获取到这个类型下所有实现类子类等等...-->
<context:property-placeholder location="classpath:dbconfig.properties"/>
<!-- username是Spring的key中的一个关键字;
为了防止配置文件中的key和spring自己的关键字冲突。我们可以给配置文件中的key加上一个前缀 -->
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="user" value="${jdbc.username}"></property>
<!-- ${ key }动态取出配置文件中某个key对应的值 -->
<property name="password" value="${jdbc.password}"></property>
<property name="jdbcUrl" value="${jdbc.jdbcUrl}"></property>
<property name="driverClass" value="${jdbc.driverClass}"></property>
</bean>
<bean id="car01" class="com.atguigu.bean.Car">
<property name="carName" value="${username}"></property>
</bean>
</beans>
实验13:基于XML的自动装配(自定义类型自动赋值)
javaBean(基本类型) (自定义类型的属性是一个对象,这个对象在容器中可能存在)
<!--实验13:基于XML的自动装配(自定义类型自动赋值)
javaBean(基本类型)
(自定义类型的属性是一个对象,这个对象在容器中可能存在)-->
<bean id="car" class="com.atguigu.bean.Car">
<property name="carName" value="宝马"></property>
<property name="color" value="白色"></property>
</bean><!-- -->
<!-- <bean id="car02" class="com.atguigu.bean.Car">
<property name="carName" value="BWM"></property>
<property name="color" value="白色"></property>
</bean> --> <!-- -->
<!-- 为Person里面的自定义类型的属性赋值
property:手动赋值
自动赋值(自动装配):自动的为属性赋值
自动装配:(仅限于对自定义类型的属性有效)
autowire="default/no":不自动装配;不自动为car属性赋值
//按照某种规则自动装配
autowire="byName":按照名字;
private Car car;
1)、以属性名(car)作为id去容器中找到这个组件,给他赋值;如果找不到就装配null;
car = ioc.getBean("car");
例子:<bean id="person" class="com.atguigu.bean.Person" autowire="byName"></bean>
(在ioc容器中找到一个id是car的组件)
autowire="byType":
private Car car;
1)、以属性的类型(Car)作为查找依据去容器中找到这个组件;car = ioc.getBean(Car.class);
如果容器中有多个这类型的组件,会报错;多一个car02时候
NoUniqueBeanDefinitionException:
No qualifying bean of type [com.atguigu.bean.Car] is defined:
expected single matching bean but found 2: car01,car02
2)、没找到呢?会装配null
例子:
<bean id="person" class="com.atguigu.bean.Person" autowire="byType"></bean>
(在ioc容器中找到一个类型是Car的组件)
autowire="constructor":
在Person.class文件中
public Person(Car car) {
this.car = car;
System.out.println("可以为car赋值的有参构造器....");
}
按照构造器进行赋值;
1)、先按照有参构造器参数的类型进行装配(成功就赋值);没有就直接为组件装配null即可。
2)、如果按照类型找到了多个 比如car01和car02;参数的名作为id继续匹配;找到就装配;找不到就null;
3)、不管怎么样都不会报错;
例子
<bean id="person" class="com.atguigu.bean.Person" autowire="constructor"></bean>
-->
<!--手动赋值-->
<bean id="person" class="com.atguigu.bean.Person" >
<property name="car" ref="car"></property>
</bean>
<!--自动赋值(自动装配) 一启动Person就有值-->
<bean id="person" class="com.atguigu.bean.Person" autowire="byType">
</bean>
<!-- List<Book> books;容器可以把容器中的所有book封装list赋值给这个属性 -->
<!--自动赋值(自动装配) 一启动Person就有值-->
<bean id="person" class="com.atguigu.bean.Person" autowire="byType">
</bean>
<bean id="book01" class="com.atguigu.bean.Book">
<property name="bookName" value="book1"></property>
</bean>
<bean id="book02" class="com.atguigu.bean.Book">
<property name="bookName" value="book2"></property>
</bean>
<bean id="book03" class="com.atguigu.bean.Book">
<property name="bookName" value="book3"></property>
</bean>
实验14:[SpEL测试I]
在SpEL中使用字面量、
引用其他bean、
引用其他bean的某个属性值、
调用非静态方法 调用静态方法、
使用运算符
<!--
实验14:[SpEL测试I](Spring Expression Language)Spring表达式语言-比EL表达式${}更强大
在SpEL中使用字面量、
引用其他bean、
引用其他bean的某个属性值、
【 调用非静态方法
调用静态方法、】
使用运算符;都支持
-->
<bean id="person04" class="com.atguigu.bean.Person">
<!-- 字面量:${}; #{} -->
<property name="salary" value="#{12345.67*12}"></property>
<!-- 引用其他bean的某个属性值、 -->
<property name="lastName" value="#{book01.bookName}"></property>
<!-- 引用其他bean、 -->
<property name="car" value="#{car}"></property>
<!--
调用静态方法: UUID.randomUUID().toString();
#{T(全类名).静态方法名(1,2)}
java.util.UUID是UUID.randomUUID().toString()的全类名
substring(0,5) 剪取字符串
-->
<property name="email" value="#{T(java.util.UUID).randomUUID().toString().substring(0,5)}"></property>
<!-- 调用非静态方法; 对象.方法名 -->
<property name="gender" value="#{book01.getBookName()}"></property>
</bean>