IOC快速入门及Sring配置bean

IOC控制反转的原理

ioc快速入门案例

1、创建文件

2、Monster

public class Monster {
    private Integer id;
    private String nickName;
    private String skill;

    public Monster() {
        System.out.println("monster创建。。。");
    }

    public Monster(Integer id, String nickName, String skill) {
        this.id = id;
        this.nickName = nickName;
        this.skill = skill;
    }

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getNickName() {
        return nickName;
    }

    public void setNickName(String nickName) {
        this.nickName = nickName;
    }

    public String getSkill() {
        return skill;
    }

    public void setSkill(String skill) {
        this.skill = skill;
    }

    @Override
    public String toString() {
        return "Monster{" +
                "id=" + id +
                ", nickName='" + nickName + '\'' +
                ", skill='" + skill + '\'' +
                '}';
    }

}

3、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">
<!--配置一个Monster bean-->
    <bean id="monstr01" class="com.spring.bean.Monster">
        <property name="id" value="100"/>
        <property name="nickName" value="牛魔王"/>
        <property name="skill" value="芭蕉扇"/>
    </bean>
</beans>

4、调用

public class IocTest {
    private ClassPathXmlApplicationContext applicationContext;

    /**
     * 加载spring容器
     */
    public void init () {
        applicationContext =
                new ClassPathXmlApplicationContext("beans.xml");
    }
    /**
     * 从bean.xml中获取bean
     */
    @Test
    public void test() {

        Object bean = applicationContext.getBean("monstr01");
        System.out.println("bean"+bean);

    }
}

spring中bean的获取方法

1、按beans.xml中的id获取(快速入门案例)

2、按类型获取// Monster.class

 /**
     * 从bean.xml中获取bean
     * 1.通过类型来获取bean对象,前提是beans.xml中只有一个这个类型的bean对象
     */
    @Test
    public void test() {

        Object bean = applicationContext.getBean(Monster.class);
        System.out.println("bean"+bean);

    }

spring配置bean

一、通过构造器(两种方式)来配置bean属性

1、方式一 <constructor-arg index="0" value="200"/>

2、方式二 <constructor-arg type="java.lang.Integer" value="300"/>

<!--  通过构造器来配置bean对象
    方式1、使用index参数来指定位置
-->
    <bean id="monstr02" class="com.spring.bean.Monster">
        <constructor-arg index="0" value="200"/>
        <constructor-arg index="1" value="白骨精"/>
        <constructor-arg index="2" value="吃人"/>
    </bean>
    <!--  通过构造器来配置bean对象
    方式2、使用type参数
-->
    <bean id="monstr03" class="com.spring.bean.Monster">
        <constructor-arg type="java.lang.Integer" value="300"/>
        <constructor-arg type="java.lang.String" value="红孩儿"/>
        <constructor-arg type="java.lang.String" value="三位真火"/>
    </bean>

二、通过P命名空间配置bean

注意在xml文件头配置 p 标签 xmlns:p="http://www.springframework.org/schema/p"

<!--通过P命名空间来配置bean对象-->
    <bean id="monstr04" class="com.spring.bean.Monster"
        p:id="400" p:nickName="蜘蛛精" p:skill="吐口水"
    />

三、bean对象引用其他bean

ref

<!--bean对象引用其他bean-->
    <bean id="master01" class="com.spring.bean.Master">
        <property name="monster" ref="monstr01"/>
        <property name="name" value="太上老君"/>
    </bean>
package com.spring.bean;

public class Master {
    private String name;
    private Monster monster;

四、配置内部bean对象

<!--配置内部bean对象-->
    <bean id="master02" class="com.spring.bean.Master">
        <property name="name" value="地藏王"/>
        <property name="monster" ref="monstr02"/>
        <property name="monster2">
            <bean class="com.spring.bean.Monster">
                <property name="id" value="500"/>
                <property name="skill" value="谛听"/>
                <property name="nickName" value="顺风耳"/>
            </bean>
        </property>
    </bean>

五、 给有List集合属性的bean赋值

public class Master {
    private String name;
    private Monster monster;

    private  Monster monster2;

    private List<Monster> monsterList;
<!--给list集合属性的bean赋值-->
    <bean id="master02" class="com.spring.bean.Master">
        <property name="name" value="地藏王"/>
        <property name="monster" ref="monstr02"/>
        <property name="monster2" ref="monstr01"/>
        <property name="monsterList">
            <list>
                <ref bean="monstr03"/>
                <ref bean="monstr04"/>
            </list>
        </property>
   @Test
    public void test03() {

        Master master = (Master)applicationContext.getBean("master03");
        List<Monster> monsterList= master.getMonsterList();
        System.out.println("master:"+master);
        for (Monster monster: monsterList){
            System.out.println("monster:"+monster);
        }

    }

 六、给有Map集合属性的bean赋值

public class Master {
    private String name;
    private Monster monster;

    private  Monster monster2;
    private Map<String,Monster> monsterMap;
  <!--给Map集合属性的bean赋值-->
    <bean id="master04" class="com.spring.bean.Master">
        <property name="name" value="地藏王"/>
        <property name="monster" ref="monstr02"/>
        <property name="monster2" ref="monstr01"/>
        <property name="monsterMap">
           <map>
               <entry>
                   <key>
                       <value>monsterMap01</value>
                   </key>
                   <ref bean="monstr03"/>
               </entry>
               <entry >
                   <key>
                       <value>monsterMap02</value>
                   </key>
                   <ref bean="monstr04"/>
               </entry>
           </map>
        </property>

    </bean>
   @Test
    public void test03() {

        Master master = (Master)applicationContext.getBean("master04");
        Map<String, Monster> monsterMap = master.getMonsterMap();
        System.out.println(monsterMap);
        for (Map.Entry<String,Monster> entry : monsterMap.entrySet()){
            System.out.println("entrykey:"+entry.getKey()+"entryValue:"+entry.getValue());

        }
    }

七、给有Property属性的bean赋值

public class Master {
    private String name;
    private Monster monster;

    private  Monster monster2;
    private Map<String,Monster> monsterMap;

    private Properties ps;
 <!--给Properties集合属性的bean赋值-->
    <bean id="master05" class="com.spring.bean.Master">
        <property name="name" value="地藏王"/>
        <property name="monster" ref="monstr02"/>
        <property name="monster2" ref="monstr01"/>
        <property name="ps">
            <props>
                <prop key="prokey01">牛魔王</prop>
                <prop key="prokey02">白骨精</prop>
            </props>
        </property>

    </bean>
    @Test
    public void test03() {

        Master master = (Master)applicationContext.getBean("master05");
        Properties ps = master.getPs();
        System.out.println("ps :"+ps);
        for (String key : ps.stringPropertyNames()) {
            System.out.println("key:"+key+"value"+ps.getProperty(key));

        }
    }

八、util名称空间的使用--创建list集合(也可以创建map、set)

注意在xml配置<util-list>标签, 标记粗体的部分

<?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:p="http://www.springframework.org/schema/p"
xmlns:util="http://www.springframework.org/schema/util"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/util
http://www.springframework.org/schema/util/spring-util.xsd">

   @Test
    public void test04() {
        List<String> list = (List<String>)applicationContext.getBean("myList");
        for (String string : list) {
            System.out.println(string);
        }
    }
<!--    创建list-->
    <util:list id="myList">
        <value>list01-string</value>
        <value>list02-string</value>
    </util:list>

九、级联属性赋值

实质上是给内嵌的bean的属性赋值

<!--    级联属性赋值-->
    <bean id="myDog" class="com.spring.bean.Dog"/>
   <bean id="myBoy" class="com.spring.bean.myBoy">
       <property name="name" value="TOM"/>
       <property name="dog" ref="myDog"/>
       <property name="Dog.name" value="哈巴狗"/>
   </bean>
public class myBoy {
    private String name;
    private Dog dog;

    public myBoy() {
    }
   @Test
    public  void test05() {
        myBoy myBoy = (myBoy)applicationContext.getBean("myBoy");
        System.out.println(myBoy.getDog().getName());

    }

十、静态工厂获取bean对象

静态工厂类(使用静态的方式生产(new)对象)

public class MyStaticFactory {
    private static Map<String,Monster> monster_map;
    static {
        monster_map  = new HashMap<String,Monster>();
        monster_map.put("monster01",new Monster(700,"大鱼怪","喝水"));
        monster_map.put("monster02",new Monster(800,"小鱼怪","喝水"));
    }
    public static Monster getMonster(String key){
        return monster_map.get(key);
    }
}
<!--    通过静态工厂获取bean-->
<bean id="myMonster" class="com.spring.bean.MyStaticFactory"
      factory-method="getMonster">  //指定获取对象的静态方法
    <constructor-arg value="monster01"/> //指定获取的key值
</bean>
  @Test
    public void test06() {
       Monster monster = (Monster)applicationContext.getBean("myMonster");
        System.out.println(monster); //静态工厂获取bean对象,最终返回的不是静态工厂类,而是生产的对象

    }

 十一、实例工厂配置bean

public class MyInstanceFactory {
    private HashMap<String,Monster> map;
    {
        map = new HashMap<String,Monster>();
        map.put("monsterkey01",new Monster(100,"小鱼怪","喝水"));
        map.put("monsterkey02",new Monster(900,"大鱼怪","喝很多水"));

    }
    public Monster getMonster(String key) {
        return map.get(key);
    }
}
<!--    通过实例工厂获取bean-->
    <bean id="myInstanceFactory" class="com.spring.bean.MyInstanceFactory"/>
    <bean id="monster2" factory-bean="myInstanceFactory" factory-method="getMonster">
        <constructor-arg value="monsterkey02"/>
    </bean>
  /**
     * 实例工厂配置bean
     */
    @Test
    public void test07() {
        Monster monster = (Monster) applicationContext.getBean("monster2");
        System.out.println(monster);
    }

十二、FactoryBean工厂获取bean对象

使用spring提供的FactoryBean<T>接口,可以简化使用工厂bean时spring容器bean.xml的配置,又可以配置是否单例(即在同一个线程中取得的对象总是同一个)

public class MyFactoryBean implements FactoryBean<Monster> {
    private String keyval;
    private  HashMap<String,Monster> map;

     {
        map = new HashMap<String,Monster>();
        map.put("monsterkey01",new Monster(100,"小mao怪","喝水"));
        map.put("monsterkey02",new Monster(900,"大猫怪","喝很多水"));

    }

    /**
     * 必需写keyval的getter,setter方法,这是规范
     * @return
     */
    public String getKeyval() {
        return keyval;
    }

    public void setKeyval(String keyval) {
        this.keyval = keyval;
    }

    /**
     * 底层会先调用setKeyval()方法
     * @return
     * @throws Exception
     */
    @Override
    public Monster getObject() throws Exception {
        return map.get(keyval);
    }

    @Override
    public Class<?> getObjectType() {
        return Monster.class;
    }

    /**
     * 在单个线程中,获取bean永远是同一个对象
     * @return
     */
    @Override
    public boolean isSingleton() {
        return true;
    }
}
<!--使用FactoryBean配置-->
    <bean id="monster3" class="com.spring.bean.MyFactoryBean">
        <property name="keyval" value="monsterkey02"/>
    </bean>
  /**
     * 使用FactoryBean接口配置实例工厂bean
     */
    @Test
    public void test08() {
        Monster monster = (Monster) applicationContext.getBean("monster3");
        System.out.println(monster);
    }

十三、bean信息的重用(类似于继承)

1、设置bean的parent属性

    <bean id="monstr01" class="com.spring.bean.Monster">
        <property name="id" value="100"/>
        <property name="nickName" value="牛魔王"/>
        <property name="skill" value="芭蕉扇"/>
    </bean>
<!--bean信息的重用-->
    <bean id="monstr20" class="com.spring.bean.Monster" parent="monstr01"/>

2、可以重写属性 值

    <bean id="monstr01" class="com.spring.bean.Monster">
        <property name="id" value="100"/>
        <property name="nickName" value="牛魔王"/>
        <property name="skill" value="芭蕉扇"/>
    </bean>
<!--bean信息的重用-->
    <bean id="20" class="com.spring.bean.Monster" parent="monstr01">
        <property name="nickName" value="200"/>
    </bean>

3、如果希望monstr01这个bean不用实例化,只是被用于bean信息重用,那么设置abstract属性为true

    <bean id="monstr30" class="com.spring.bean.Monster" abstract="true">
        <property name="id" value="100"/>
        <property name="nickName" value="牛魔王"/>
        <property name="skill" value="芭蕉扇"/>
     </bean>
<!--bean信息的重用-->
    <bean id="monstr20" class="com.spring.bean.Monster" parent="monstr30">
        <property name="id" value="200"/>
    </bean>

十四、bean的创建顺序问题

在spring的ioc容器,在默认情况下是按照配置的顺序来创建的比如

<bean id="student01"class="com.itbull.bean.Student"/>
<bean id="department01"class="com.itbull.bean.Department"/>


会先创建student01这个bean对象,然后创建department01这个bean
但是,如果这样配置

<bean id="student01"class="com.itbull.bean.Student" depends-on="department01"/><bean id="department01" class="com.itbull.bean.Department"/>


就会先创建department01bean,再创建student01这个bean.
说明
1.默认情况下是按照顺序来创建bean
2.如果确实有依赖关系,你以通过调整顺序或者使用 depends-on来说明

十五、bean单实例与多实例的说明(重点)

 在spring的ioc容器,在默认情况下是按照单例创建的,即配置一个bean对象后,ioc容器只会创建一个bean实例。
如果,我们希望ioc容器配置的某个bean对象,是以多个实例形式创建的则可以通过配置scope="prototype"来指定

 <bean id="monstr21" class="com.spring.bean.Monster" scope="prototype"/>
    @Test
    public void test08() {
        Monster monster1 = (Monster) applicationContext.getBean("monstr21");
        Monster monster2 = (Monster) applicationContext.getBean("monstr21");

        System.out.println(monster1.hashCode());
        System.out.println(monster2.hashCode());
    }


细节说明:
1.默认是单例,当<bean scope="prototype">设置为多实例机制
2.设置为scope="prototype"后,该bean是在getBean时才创建。

十六、配置有生命周期的bean

每个bean都会有一个初始化,销毁的过程。配置有生命周期的bean,即可以在初始化与销毁的时点做些事儿

public class Cat {
    private String name;

    public Cat() {
        System.out.println("cat无参构造方法被调用");
    }

    public Cat(String name) {
        this.name = name;
        System.out.println("cat有参构造方法被调用");
    }
    public void init() {
        System.out.println("小猫被初始化了,取名叫小黄");
    }
    public void  play() {
        System.out.println(this.name+"正在快乐地玩耍");
    }
    public void destroy() {
        System.out.println(this.name+"活了一百岁,安息");
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}
<!--    配置有生命周期的bean-->
    <bean id="cat1" class="com.spring.bean.Cat" init-method="init" destroy-method="destroy">
        <property name="name" value="宝宝"/>
    </bean>
    @Test
    public void test08() {
        Cat cat1 = (Cat) applicationContext.getBean("cat1");
       cat1.play();
        ConfigurableApplicationContext cac = (ConfigurableApplicationContext) applicationContext;
        cac.close();
        System.out.println("程序没有退出");
    }

 十七、配置后置处理器

        如果在IOC容器中bean配置了init()方法(什么是init方法请看十五),此时希望可以在init()方法被调用的前后做一些设置比如记录日志,或者过滤,那么可以考虑使用后置处理器。

        具体用法如下

十八、通过属性文件注入值

之前在学习集合时,学习过map接口的实现类properties类,可以将例如JDBC的配置信息写在.properties文件中。

1、在源码目录src下,new一个File文件,取名my.properties,写上monster类的键值对

2、配置xml标签声明

xmlns:context="http://www.springframework.org/schema/context"

xsi:schemaLocation=“http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">”

在bean.xml中引用

<!--通过属性文件注入值-->
    <context:property-placeholder location="classpath:my.properties"/>
    <bean id="monster99" class="com.spring.bean.Monster">
        <property name="id" value="${monster.id}"/>
        <property name="nickName" value="${monster.name}"/>
        <property name="skill" value="${monster.skill}"/>
    </bean>

3、

   /**
     *通过属性文件注入值
     */
    @Test
    public void test09() {
        Monster monster = (Monster) applicationContext.getBean("monster99");
        System.out.println(monster.toString());
    }

十九、 Spring基于xml自动装配bean

        当Action-service-Dao三层架构的情况下,如果不使用ref如何配置bean.xml呢?使用bean的autowire属性,来配置

具体说明:

        1、先看一个传统SSH框架的Action-service-Dao的写法(ref)

public class OrderDao {
    public void save(){
        System.out.println("save了一个对象");
    }

    public OrderDao() {
    }
}
import com.spring.orderDao.OrderDao;

public class OrderService {
    private OrderDao orderDao;

    public OrderService() {
    }

    public OrderDao getOrderDao() {
        return orderDao;
    }

    public void setOrderDao(OrderDao orderDao) {
        this.orderDao = orderDao;
    }
    public void save(){
        orderDao.save();
    }
}
import com.spring.orderService.OrderService;

public class OrderAcion {
    private OrderService orderService;

    public OrderAcion() {
    }

    public OrderService getOrderService() {
        return orderService;
    }

    public void setOrderService(OrderService orderService) {
        this.orderService = orderService;
    }
    public void save() {
        orderService.save();
    }
}
<!--    传统方式配置Action-Service-Dao-->
    <bean id="orderDao" class="com.spring.orderDao.OrderDao" />
    <bean id="orderService" class="com.spring.orderService.OrderService">
        <property name="orderDao" ref="orderDao"/>
    </bean>
    <bean id="orderAction" class="com.spring.orderAction.OrderAcion">
        <property name="orderService" ref="orderService"/>
    </bean>
    /**
     *通过属性文件注入值
     */
    @Test
    public void test10() {
        OrderAcion orderAcion = (OrderAcion) applicationContext.getBean("orderAction");
        orderAcion.save();
    }

2、spring基于xml的自动装配

(1)利用bean的autowire="byType"。

1>spring 容器先构造了orderDao

2>

在spring容器构造orderService时发现有autowire="byType",那么就会去看orderService类有什么类需要装配即有什么属性是对象类的,然后j将orderDao装配给orderService.

3>“装配”最终表现为,  OrderAcion orderAcion = (OrderAcion) applicationContext.getBean("orderAction");
        orderAcion.save(); 输出为 save了一个对象

<!--   spring基于xml的自动装配1-->
    <bean id="orderDao" class="com.spring.orderDao.OrderDao"/>
    <bean id="orderService" autowire="byType" class="com.spring.orderService.OrderService"/>
    <bean id="orderAction" autowire="byType" class="com.spring.orderAction.OrderAcion"/>

 (2)方式一bytype只能是当orderDao只有一个bean时使用,当多个orderDao的bean时,使用byname。 

注意byName的依据是 orderService的 setOrderDao2方法, 即orderService的这个set方法名称与bean id="orderDao2"相同

    <!--   spring基于xml的自动装配2-->
    <bean id="orderDao2" class="com.spring.orderDao.OrderDao"/>
    <bean id="orderService" autowire="byName" class="com.spring.orderService.OrderService"/>
    <bean id="orderAction" autowire="byName" class="com.spring.orderAction.OrderAcion"/>

辅助说明 

二十、使用spel表达式为属性赋值

spel表达式公式: #{spel公式}

<!--    使用spel表达式为属性赋值-->
    <bean id="spelBean" class="com.spring.bean.SpelBean">
<!--        使用字面量赋值-->
        <property name="beanName" value="#{'snowdream雪'}"/>
<!--        使用其他bean的属性赋值-->
        <property name="monsterName" value="#{monstr01.nickName}"/>
<!--        直接使用其他bean赋值-->
        <property name="monster" value="#{monstr02}"/>
<!--        使用方法的返回值赋值-->
        <property name="result" value="#{spelBean.getSum(2.0,3.0)}"/>
<!--        使用静态方法的返回值赋值-->
        <property name="bookName" value="#{T(com.spring.bean.SpelBean).readBook('爱你一万年')}"/>
    </bean>

public class SpelBean {
    //在spring容器中,使用Spel表达式来给属性赋值
    private String beanName;
    private String monsterName;
    private Monster monster;
    private Double result;
    private String bookName;

    public SpelBean() {
    }

    public String getBeanName() {
        return beanName;
    }

    public void setBeanName(String beanName) {
        this.beanName = beanName;
    }

    public String getMonsterName() {
        return monsterName;
    }

    public void setMonsterName(String monsterName) {
        this.monsterName = monsterName;
    }

    public Monster getMonster() {
        return monster;
    }

    public void setMonster(Monster monster) {
        this.monster = monster;
    }

    public Double getResult() {
        return result;
    }

    public void setResult(Double result) {
        this.result = result;
    }

    public String getBookName() {
        return bookName;
    }

    public void setBookName(String bookName) {
        this.bookName = bookName;
    }

    public SpelBean(String beanName, String monsterName, Monster monster, Double result, String bookName) {
        this.beanName = beanName;
        this.monsterName = monsterName;
        this.monster = monster;
        this.result = result;
        this.bookName = bookName;
    }
    public Double getSum(double a,double b) {
        return a+b;
    }
    public static String readBook(String s) {
        return s;
    }

    @Override
    public String toString() {
        return "SpelBean{" +
                "beanName='" + beanName + '\'' +
                ", monsterName='" + monsterName + '\'' +
                ", monster=" + monster +
                ", result=" + result +
                ", bookName='" + bookName + '\'' +
                '}';
    }
}

  /**
     * 使用spel表达式赋值
     */
    @Test
    public void test11() {
        SpelBean spelBean = (SpelBean) applicationContext.getBean("spelBean");
        System.out.println(spelBean);
    }

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值