文章目录
- 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对象@Testpublic 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对象@Testpublic 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对象@Overridepublic Monster getObject() throws Exception {return this.monsterMap.get(key);}//返回bean对象的类型@Overridepublic Class<?> getObjectType() {return Monster.class;}//返回是否是单例的@Overridepublic 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对象@Testpublic 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配置信息重用@Testpublic 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.测试
//生命周期案例演示@Testpublic void lifeCycle() {//1.反射创建bean对象,2.依赖注入ApplicationContext ioc = new ClassPathXmlApplicationContext("beans.xml");//3.初始化bean//4.getBeanHouse 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*/@Overridepublic 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*/@Overridepublic 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.测试
//后置处理器演示@Testpublic 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@Testpublic 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自动装配@Testpublic 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());}