文章目录
- 1.工厂中获取bean
- 1.静态工厂
- 1.MyStaticFactory.java
- 2.beans.xml
- 3.测试
- 2.实例工厂
- 1.MyInstanceFactory.java
- 2.beans.xml
- 3.测试
- 3.FactoryBean(重点)
- 1.MyFactoryBean.java
- 2.beans.xml
- 3.测试
- 2.bean配置信息重用
- 继承抽象bean
- 1.beans.xml
- 2.测试
- 3.bean细节介绍
- 1.bean的创建顺序
- 1.depends-on关键字
- 2.问题引出
- 2.bean对象的单例和多例
- 1.应用实例
- 2.使用细节
- 3.单例与多例对比
- 单例(非懒加载)
- 单例(懒加载)
- 多例
- 3.bean的生命周期
- 1.基本介绍
- 2.简化来说
- 3.生命周期演示案例
- 1.House.java
- 2.beans.xml
- 3.测试
- 4.配置bean后置处理器(难点)
- 1.MyBeanPostProcessor.java
- 2.beans02.xml
- 3.测试
- 5.通过属性文件配置bean
- 1.src下创建my.properties
- 2.beans03.xml
- 3.测试
- 6.自动装配bean
- 1.OrderDao.java
- 2.OrderService.java
- 3.OrderServlet.java
- 4.通过类型自动装配
- 5.通过名字自动装配
- 6.测试
- 7.Spring El表达式(了解)
1.工厂中获取bean
1.静态工厂
1.MyStaticFactory.java
package com.sxs.spring.bean;
import java.util.HashMap;
import java.util.Map;
/**
* @author 孙显圣
* @version 1.0
*/
public class MyStaticFactory {
//hashmap存储对象
private static Map<String, Monster> monsterHashMap;
//静态代码块进行初始化
static {
monsterHashMap = new HashMap<>();
//放进去两个对象
monsterHashMap.put("monster01", new Monster(1, "牛魔王", "芭蕉扇"));
monsterHashMap.put("monster01", new Monster(2, "牛魔王", "芭蕉扇"));
}
//提供get方法获取bean对象
public static Monster getMonster(String key) {
return monsterHashMap.get(key);
}
}
2.beans.xml
<!--静态工厂获取bean-->
<!--不需要创建MyStaticFactory的对象,通过类加载就可以初始化工厂-->
<bean class="com.sxs.spring.bean.MyStaticFactory" id="staticFactory" factory-method="getMonster">
<constructor-arg value="monster01"/>
</bean>
3.测试
//静态工厂获取bean对象
@Test
public void staticFactory() {
ApplicationContext ioc = new ClassPathXmlApplicationContext("beans.xml");
Monster bean = ioc.getBean("staticFactory", Monster.class);
System.out.println(bean);
}
2.实例工厂
1.MyInstanceFactory.java
package com.sxs.spring.bean;
import java.util.HashMap;
import java.util.Map;
/**
* @author 孙显圣
* @version 1.0
*/
public class MyInstanceFactory {
//map存储monster对象
private Map<String, Monster> monsterMap;
//普通代码块进行初始化
{
monsterMap = new HashMap<>();
//放进去两个对象
monsterMap.put("monster01", new Monster(1, "牛魔王", "芭蕉扇"));
monsterMap.put("monster01", new Monster(2, "牛魔王", "芭蕉扇"));
}
//提供get方法获取对象
public Monster getMonster(String key) {
return monsterMap.get(key);
}
}
2.beans.xml
<!--实例工厂获取bean-->
<!--创建bean对象,初始化两个实例工厂-->
<bean class="com.sxs.spring.bean.MyInstanceFactory" id="instanceFactory1"/>
<bean class="com.sxs.spring.bean.MyInstanceFactory" id="instanceFactory2"/>
<!--从第一个bean工厂中获取bean对象-->
<bean class="com.sxs.spring.bean.MyInstanceFactory" factory-bean="instanceFactory1" id="instanceFactory_1" factory-method="getMonster">
<constructor-arg value="monster01"/>
</bean>
<!--从第二个bean工厂中获取bean对象-->
<bean class="com.sxs.spring.bean.MyInstanceFactory" factory-bean="instanceFactory2" id="instanceFactory_2" factory-method="getMonster">
<constructor-arg value="monster01"/>
</bean>
3.测试
//通过实例工厂获取bean对象
@Test
public void instanceFactory() {
ApplicationContext ioc = new ClassPathXmlApplicationContext("beans.xml");
//从第一个实例工厂中获取bean对象
Monster monster1 = ioc.getBean("instanceFactory_1", Monster.class);
//从第二个实例工厂中获取bean对象
Monster monster2 = ioc.getBean("instanceFactory_2", Monster.class);
System.out.println(monster1 == monster2);
}
3.FactoryBean(重点)
1.MyFactoryBean.java
package com.sxs.spring.bean;
import org.springframework.beans.factory.FactoryBean;
import java.util.HashMap;
import java.util.Map;
/**
* @author 孙显圣
* @version 1.0
*/
public class MyFactoryBean implements FactoryBean<Monster> {
//bean工厂中的key,要取的key是什么就设置成什么
private String key;
//bean工厂
private Map<String, Monster> monsterMap;
//初始化bean工厂
{
monsterMap = new HashMap<>();
//放进去两个对象
monsterMap.put("monster01", new Monster(1, "牛魔王", "芭蕉扇"));
monsterMap.put("monster02", new Monster(2, "牛魔王", "芭蕉扇"));
}
//设置key的方法(用于属性注入)
public void setKey(String key) {
this.key = key;
}
//根据key返回要得到的bean对象
@Override
public Monster getObject() throws Exception {
return this.monsterMap.get(key);
}
//返回bean对象的类型
@Override
public Class<?> getObjectType() {
return Monster.class;
}
//返回是否是单例的
@Override
public boolean isSingleton() {
return true;
}
}
2.beans.xml
<!--通过FactoryBean来获取bean-->
<bean class="com.sxs.spring.bean.MyFactoryBean" id="myFactoryBean">
<!--直接对要获取的key进行属性注入即可-->
<property name="key" value="monster01"/>
</bean>
3.测试
//通过factorybean获取bean对象
@Test
public void factoryBean() {
ApplicationContext ioc = new ClassPathXmlApplicationContext("beans.xml");
Monster myFactoryBean = ioc.getBean("myFactoryBean", Monster.class);
System.out.println(myFactoryBean);
}
2.bean配置信息重用
继承抽象bean
1.beans.xml
<!--抽象bean对象,不能够被实例化只能够被继承,-->
<bean class="com.sxs.spring.bean.Monster" id="Abstractmonster" abstract="true">
<property name="monsterId" value="200"/>
<property name="name" value="孙悟空"/>
<property name="skill" value="金箍棒"/>
</bean>
<!--继承抽象bean对象(也可以继承抽象的bean对象),则属性与其一样-->
<bean class="com.sxs.spring.bean.Monster" id="monster3" parent="Abstractmonster"/>
2.测试
//bean配置信息重用
@Test
public void configureInformationReuse() {
ApplicationContext ioc = new ClassPathXmlApplicationContext("beans.xml");
Monster monster03 = ioc.getBean("monster3", Monster.class);
System.out.println(monster03);
}
3.bean细节介绍
1.bean的创建顺序
1.depends-on关键字
<!--默认情况下是car5先创建,但是如果有depends-on绑定了car6,则在获取容器的时候是car6先创建-->
<bean class="com.sxs.spring.bean.Car" id="car5" depends-on="car6"/>
<bean class="com.sxs.spring.bean.Car" id="car6"/>
2.问题引出
2.bean对象的单例和多例
1.应用实例
<!--单例模式,默认的,每次都读取配置文件反射创建对象,然后将其放到容器中的字段里-->
<bean class="com.sxs.spring.bean.Monster" id="monster4" scope="singleton"/>
<!--多例模式,每次getBean的时候才会创建新对象-->
<bean class="com.sxs.spring.bean.Monster" id="monster5" scope="prototype"/>
2.使用细节
3.单例与多例对比
单例(非懒加载)
- 获取ioc容器
- 读取配置文件
- 反射创建bean对象
- 放到ioc容器的字段中
- getBean直接从字段中获取
单例(懒加载)
- 获取ioc容器
- 读取配置文件
- getBean的时候创建bean对象
- 将bean对象放到ioc容器的字段中
- 下次getBean还是从该字段中获取
多例
- 获取ioc容器
- 读取配置文件
- getBean的时候创建bean对象
- 下次getBean再穿件bean对象
3.bean的生命周期
1.基本介绍
2.简化来说
- 反射创建bean对象
- 依赖注入
- 初始化bean
- getBean
- 销毁bean(容器关闭才会调用)
3.生命周期演示案例
1.House.java
package com.sxs.spring.bean;
/**
* @author 孙显圣
* @version 1.0
*/
public class House {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
System.out.println("setName方法被调用!");
this.name = name;
}
//自定义的初始化方法,名字可以任意
public void init() {
System.out.println("bean初始化");
}
//自定义的销毁方法密码,名字可以任意
public void destory() {
System.out.println("bean对象被销毁");
}
}
2.beans.xml
<!--bean生命周期案例-->
<bean class="com.sxs.spring.bean.House" id="house" init-method="init" destroy-method="destory">
<property name="name" value="北京豪宅"/>
</bean>
3.测试
//生命周期案例演示
@Test
public void lifeCycle() {
//1.反射创建bean对象,2.依赖注入
ApplicationContext ioc = new ClassPathXmlApplicationContext("beans.xml");
//3.初始化bean
//4.getBean
House house = ioc.getBean("house", House.class);
//5.销毁bean
((ConfigurableApplicationContext)ioc).close();
}
4.配置bean后置处理器(难点)
1.MyBeanPostProcessor.java
package com.sxs.spring.bean;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
/**
* @author 孙显圣
* @version 1.0
*/
//bean的后置处理器对象
public class MyBeanPostProcessor implements BeanPostProcessor {
/**
* 在bean的init方法前被调用
* @param bean 传入的在ioc容器中创建的bean
* @param beanName 传入的在ioc容器中配置的bean的id
* @return
* @throws BeansException
*/
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
//判断是否bean对象是house,如果是,将名字改为豪宅
if (bean instanceof House) {
((House) bean).setName("豪宅");
}
System.out.println("postProcessBeforeInitialization被调用 " + bean + "beanName=" + beanName);
return bean;
}
/**
* 在bean的init方法后被调用
* @param bean
* @param beanName
* @return
* @throws BeansException
*/
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
System.out.println("postProcessAfterInitialization被调用 " + bean + "beanName=" + beanName);
return bean;
}
}
2.beans02.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">
<!--配置bean的后置处理器,会作用于所有的bean-->
<bean class="com.sxs.spring.bean.MyBeanPostProcessor" id="beanPostProcessor"/>
<bean class="com.sxs.spring.bean.House" id="house" init-method="init" destroy-method="destory">
<property name="name" value="北京豪宅"/>
</bean>
<bean class="com.sxs.spring.bean.House" id="house02" init-method="init" destroy-method="destory">
<property name="name" value="香港豪宅"/>
</bean>
</beans>
3.测试
//后置处理器演示
@Test
public void MyBeanPostProcessor() {
ApplicationContext ioc = new ClassPathXmlApplicationContext("beans02.xml");
House house = ioc.getBean("house", House.class);
//关闭bean
((ConfigurableApplicationContext)ioc).close();
}
5.通过属性文件配置bean
1.src下创建my.properties
如果是中文则自己将中文转换成unicode编码
name=jack
skill=\u5403\u996d
monsterId=111
2.beans03.xml
<!--设置配置文件的位置-->
<context:property-placeholder location="classpath:my.properties"/>
<!--使用${name}来读取配置文件中的信息-->
<bean class="com.sxs.spring.bean.Monster" id="monster">
<property name="name" value="${name}"/>
<property name="skill" value="${skill}"/>
<property name="monsterId" value="${monsterId}"/>
</bean>
3.测试
//测试使用配置文件配置bean
@Test
public void profiles() {
ApplicationContext ioc = new ClassPathXmlApplicationContext("beans03.xml");
Monster monster = ioc.getBean("monster", Monster.class);
System.out.println(monster);
}
6.自动装配bean
1.OrderDao.java
package com.sxs.spring.dao;
/**
* @author 孙显圣
* @version 1.0
*/
public class OrderDao {
public void saveOrder() {
System.out.println("保存订单");
}
}
2.OrderService.java
package com.sxs.spring.service;
import com.sxs.spring.dao.OrderDao;
/**
* @author 孙显圣
* @version 1.0
*/
public class OrderService {
OrderDao orderDao;
public OrderDao getOrderDao() {
return orderDao;
}
public void setOrderDao(OrderDao orderDao) {
this.orderDao = orderDao;
}
}
3.OrderServlet.java
package com.sxs.spring.web;
import com.sxs.spring.service.OrderService;
/**
* @author 孙显圣
* @version 1.0
*/
public class OrderServlet {
OrderService orderService;
public OrderService getOrderService() {
return orderService;
}
public void setOrderService(OrderService orderService) {
this.orderService = orderService;
}
}
4.通过类型自动装配
<!--根据类型自动装配,会查找容器中是否有类型与属性一致的bean对象,如果有则自动注入-->
<!--使用类型类自动装配的话,需要保证容器中只有一个同类型的bean对象-->
<bean class="com.sxs.spring.dao.OrderDao" id="orderDao"/>
<bean autowire="byType" class="com.sxs.spring.service.OrderService" id="orderService"/>
<bean autowire="byType" class="com.sxs.spring.web.OrderServlet" id="orderServlet"/>
5.通过名字自动装配
<!--根据名字自动装配,会查找容器中是否有与属性名字相同的id-->
<bean class="com.sxs.spring.dao.OrderDao" id="orderDao"/>
<bean autowire="byName" class="com.sxs.spring.service.OrderService" id="orderService"/>
<bean autowire="byName" class="com.sxs.spring.web.OrderServlet" id="orderServlet"/>
6.测试
//测试使用autowire自动装配
@Test
public void setBeanByAutowire() {
ApplicationContext ioc = new ClassPathXmlApplicationContext("beans03.xml");
OrderServlet bean = ioc.getBean(OrderServlet.class);
//验证是否装配成功
System.out.println(bean.getOrderService());
System.out.println(bean.getOrderService().getOrderDao());
}