最近看到一些帖子 很多内容不明白 应该开始理解一下基础,不能只会用 所以博主决定重学一下SSM 和一些基础重点。
目录
内部bean 可以不配置id ,这样其它的bean就无法引用的.
给bean对象的集合类型属性赋值 (这里的集合看成bean的一个属性即可)
通过FactoryBean获取bean对象(重点/后面要用)
Spring是什么?
Spring是一个轻量级框架集合,是业务逻辑层和其他各层的松耦合问题。
Spring有两个核心的概念: IOC 和 AOP (还有一个JdbcTemplate 一种管理数据库的机制)
IOC (Inversion Of Control控制反转)
什么是IOC :不是技术,是一种设计思想!!!!!
传统开发:需要自己在程序中new对象来使用
使用IOC容器后: 对象都在IOC容器中创建 不需要你手动创建
Bean的配置和获取方式
配置bean
- 基于xml配置Bean
- 使用注解定义Bean
- 基于java类提供Bean定义信息
具体操作不做说明 需要了解 传送门
本文用的bean
获取bean的方法
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("beans.xml");
Object bean = applicationContext.getBean("这里是bean的ID");
配置bean的属性
1.通过构造器来获取
第一种是通过<property>标签
<bean id="monster01" class="com.fy.spring.bean.Monster" >
<property name="id" value="100" />
<property name="nickname" value="~牛魔王~" />
<property name="skill" value="芭蕉扇" />
</bean>
第二种是通过<constructor-arg>标签
方式1: 同index 来指定参数位置
<bean id="monster02" class="com.fy.spring.bean.Monster">
<constructor-arg index="0" value="200" />
<constructor-arg index="1" value="白骨精" />
<constructor-arg index="2" value="吃人" />
</bean>
方式2: 用类型来来指定参数位置
<bean id="monster03" class="com.fy.spring.bean.Monster">
<constructor-arg type="Integer" value="300" />
<constructor-arg type="String" value="红孩儿" />
<constructor-arg type="String" value="三位真火" />
</bean>
2.通过P标签获取
<bean id="monster04" class="com.fy.spring.bean.Monster"
p:id="400"
p:nickname="蜘蛛精"
p:skill="吐口水"
/>
内部bean 可以不配置id ,这样其它的bean就无法引用的.
<!-- 配置一个master bean对象, 含有内部bean -->
<bean id="master02" class="com.fy.spring.bean.Master">
<property name="name" value="地藏王" />
<property name="monster" ref="monster02" /> //ref 是引用的意思
<property name="monster2">
<bean class="com.fy.spring.bean.Monster">
<property name="id" value="500"/>
<property name="nickname" value="谛听"/>
<property name="skill" value="顺风耳"/>
</bean>
</property>
</bean>
给bean对象的集合类型属性赋值 (这里的集合看成bean的一个属性即可)
<!-- 配置一个master bean对象 ,还有List集合属性 -->
<bean id="master03" class="com.fy.spring.bean.Master">
<property name="name" value="地藏王" />
<property name="monster" ref="monster02" />
<property name="monster2" ref="monster01" />
<property name="monsterList">
<list>
<ref bean="monster03"/>
<ref bean="monster04"/>
</list>
</property>
</bean>
<!-- 配置一个master bean对象 ,还有map集合属性 -->
<bean id="master04" class="com.fy.spring.bean.Master">
<property name="name" value="~地藏王~" />
<property name="monster" ref="monster02" />
<property name="monster2" ref="monster01" />
<property name="map">
<map>
<entry>
<key>
<value>monstermap01</value>
</key>
<ref bean="monster03"/>
</entry>
<entry>
<key>
<value>monstermap02</value>
</key>
<ref bean="monster04"/>
</entry>
</map>
</property>
</bean>
<!-- 配置一个master bean对象 ,有properties集合属性 -->
<!--说明一下Properties 集合的特点
(1).这个Properties 是 Hashtable的子类 , 是key-value的形式
(2).key 是 string 而 value 也是 string -->
<bean id="master05" class="com.fy.spring.bean.Master">
<property name="name" value="~地藏王~" />
<property name="monster" ref="monster02" />
<property name="monster2" ref="monster01" />
<property name="ps">
<props>
<prop key="prokey01">牛魔王</prop>
<prop key="prokey02">白骨精</prop>
</props>
</property>
</bean>
util名称空间创建list集合
<util:list id="myList">
<value>list值1-string</value>
<value>list值2-string</value>
</util:list>
获取方法: List<String> listStr = (List<String>) applicationContext.getBean("myList");
for (String string : listStr) {
System.out.println("val=" + string);
}
级联属性赋值(这个可能用的机会很少)
<bean id="myDog" class="com.fy.spring.bean.Dog"/>
<bean id="myBoy" class="com.fy.spring.bean.Boy">
<property name="name" value="tom" />
<property name="dog" ref="myDog"/>
<!-- 级联属性赋值 -->
<property name="dog.name" value="哈趴狗"/>
</bean>
静态工厂创建bean
需要先创建一个静态工厂
public class MyStaticFactory {
private static HashMap<String,Monster> map;
//静态块
static{
map = new HashMap<String, Monster>();
map.put("monsterkey01", new Monster(700, "小鱼怪", "喝水"));
map.put("monsterkey02", new Monster(800, "大鱼怪", "喝很多水"));
}
public static Monster getMonster(String key){
return map.get(key);
}
}
<!-- 通过静态工厂获取bean对象 -->
<bean id="myMonster" class="com.itbull.spring.bean.MyStaticFactory"
factory-method="getMonster">
<constructor-arg value="monsterkey02"/>
</bean>
实例工厂
public class MyInstaneFactory {
private HashMap<String,Monster> map;
//代码块
{
map = new HashMap<String, Monster>();
map.put("monsterkey01", new Monster(900, "~小鱼怪~", "喝水"));
map.put("monsterkey02", new Monster(1000, "~大鱼怪~", "喝很多水"));
}
public Monster getMonster(String key){
return map.get(key);
}
}
<!-- 通过实例工厂获取bean对象 -->
<bean id="myInstaneFactory"
class="com.fy.spring.bean.MyInstaneFactory"/>
<!-- 从myInstaneFactory获取 -->
<bean id="myMonster2" factory-bean="myInstaneFactory"
factory-method="getMonster" >
<constructor-arg value="monsterkey01"/>
</bean>
通过FactoryBean获取bean对象(重点/后面要用)
public class MyFactoryBean implements FactoryBean<Monster>{
private String keyVal;
private Map<String,Monster> map;
{
map = new HashMap<String, Monster>();
map.put("monsterkey01", new Monster(900, "~小猫怪~", "抓老鼠"));
map.put("monsterkey02", new Monster(1000, "~大猫怪~", "抓很多老虎"));
}
/**
* 这个是用于接收你需要哪个key对应的monster
* @param keyVal
*/
public void setKeyVal(String keyVal) {
System.out.println("keyval = " + keyVal);
this.keyVal = keyVal;
}
/**
* 就是返回的bean
*/
@Override
public Monster getObject() throws Exception {
System.out.println("getobject key" + keyVal);
// TODO Auto-generated method stub
return map.get(keyVal);
}
/**
* 返回的bean对象的类型
*/
@Override
public Class<?> getObjectType() {
// TODO Auto-generated method stub
return Monster.class;
}
/**
* 是否以单例的方式返回 。
*/
@Override
public boolean isSingleton() {
// TODO Auto-generated method stub
return true;
}
}
<!-- 使用factoryBean获取设置bean -->
<bean id="myMonster3" class="com.fy.spring.bean.MyFactoryBean">
<property name="keyVal" value="monsterkey02" />
</bean>
bean配置信息重用(继承)
<!-- 希望创建一个monster对象,他的值和 monster01一样
注意 : 如果我们希望某个bean是值用于继承,本身不能被实例化,则将这个bean 设置为 abstract=ture
-->
<bean id="monster10" class="com.fy.spring.bean.Monster" parent="monster20"/>
bean创建的顺序问题
在spring的ioc容器, 在默认情况下是按照配置的顺序来创建的比如
<bean id="student01" class="com.fy.bean.Student" />
<bean id="department01" class="com.fy.bean.Department" />
会先创建student01这个bean对象,然后创建department01这个bean对象,
但是,如果这样配置就会先创建department01bean,再创建student01这个bean.
<bean id="student01" class="com.fy.bean.Student" depends-on="department01"/>
<bean id="department01" class="com.fy.bean.Department" />
bean对象的单例和多实例(重点)
不了解单例和多例的看下这个 传送门
单例打印出来的Hashcode是同一个地址
在spring的ioc容器, 在默认情况下是按照单例创建的,即配置一个bean对象后,ioc容器只会创建一个bean实例。
如果,我们希望ioc容器配置的某个bean对象,是以多个实例形式创建的则可以通过配置 scope="prototype" 来指定
细节说明:
默认是单例,当 <bean scope="prototype" > 设置为多实例机制
设置为 scope="prototype" 后,该bean是在getBean时才创建。
配置有生命周期的bean
public class Cat {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Cat() {
System.out.println("cat被出生了了!");
}
//初始化的方法
public void init() {
// TODO Auto-generated method stub
System.out.println("小猫被初始化, 给他取名 " + this.name);
}
public Cat(String name) {
super();
this.name = name;
}
public void play(){
System.out.println(this.name + " 快乐的玩耍");
}
//销毁方法
public void destory() {
// TODO Auto-generated method stub
System.out.println(this.name + "活了 100岁,安息..");
}
}
在spring的ioc容器,配置有生命周期的bean 即 创建/初始化/销毁。
<bean id="myCat2" class="com.fy.spring.bean.Cat"
init-method="init" destroy-method="destory">
<property name="name" value="~糖宝~"/>
</bean>
1.创建就是调用bean的构造函数,初始化就是 init方法(名字是程序员来确定的,根据你的业务逻辑来确定你需要什么时候进行初始化)。
2.销毁方法就是当关闭容器时,才会被销毁
测试结果
public void test12() {
Cat cat = (Cat) applicationContext.getBean("myCat2");
cat.play();
//关闭容器..
ConfigurableApplicationContext cac =
(ConfigurableApplicationContext) applicationContext;
cac.close();
System.out.println("程序没有退出 ");
}
cat被出生了了!
小猫被初始化, 给他取名 ~糖宝~
~糖宝~ 快乐的玩耍
~糖宝~活了 100岁,安息..
程序没有退出
配置bean的后置处理器 (有点类似AOP切面编程)
实现BeanPostProcessor接口
public class MyBeanPostProcessor implements BeanPostProcessor{
@Override
public Object postProcessBeforeInitialization(Object bean, String name)
throws BeansException {
// TODO Auto-generated method stub
System.out.println("初始化方法前被调用!" + bean.getClass());
return bean;
}
@Override
public Object postProcessAfterInitialization(Object bean, String name)
throws BeansException {
System.out.println("初始化方法后被调用!");
// TODO Auto-generated method stub
return bean;
}
}
在xml文件中配置
<!-- 配置自己的后置处理器 -->
<bean id="myBeanPostProcessor" class="com.fy.spring.bean.MyBeanPostProcessor"/>
通过属性文件给bean注入值
<!-- 引入我们的my.properties文件 引入context名字空间-->
<context:property-placeholder location="classpath:my.properties"/>
<!-- 通过外部的一个属性文件来初识化一个monster -->
<bean id="monster99" class="com.itbull.spring.bean.Monster">
<property name="id" value="${monster.id}" />
<property name="nickname" value="${monster.name}" />
<property name="skill" value="${monster.skill}" />
</bean>
</beans>
文件类容
monster.id=1000
monster.name=\u72d0\u72f8\u7cbe
monster.skill=\u7f8e\u4eba\u8ba1
基于XML的bean的自动装配
1.我们的自动装配主要是使用byname 和 bytype
2.这个知识点作为了解即可,后面我们主要还是使用基于注解的方式来玩