spring框架入门--三种方式配置Bean

spring框架的核心在于“Ioc控制反转”“DI依赖注入”以及“AOP面向切面编程”,所以在实现这些核心是最基础的一步即为在ioc容器中配置bean标签,因为我们获取对象是通过获取bean 来获得的,所以配置好bean,要用对象时我们才能想用就拿.今天查看了一下资料,总结了以下三种方式来配置Bean.(自己定义成三种的,每个人按照自己不同标准可以划分很多种的

首先先看一下准备的示例类:
1.一个Hello实体类,定义了name和person属性
2.一个Person实体类定义了name属性
(注:这里之所以提供两个实体类,是为了体现DI依赖注入的特性,这也是配置bean 中非常重要的一点)
3.测试类–junit下面做的测试
4.其他类–根据不同的方法来创建

//Hello类
package com.yc.spring;

import org.springframework.beans.factory.annotation.Autowired;

public class Hello {
    private String name;
    /* @Autowired//自动注入对象 */
    private Person person;

    public Hello() {
        System.out.println("我是hello的构造方法");
    }

    public Hello(String name, Person person) {
        super();
        this.name = name;
        this.person = person;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Person getPerson() {
        return person;
    }

    public void setPerson(Person person) {
        this.person = person;
    }

    public void sayHello() {
        System.out.println(String.format("%s 对 %s说你好帅!!!", name,
                person.getname()));
    }

}
Person类,person作为Hello类的一个属性,所以Hello类依赖于Person类
package com.yc.spring;

public class Person {
    String name;
    @Override
    public String toString() {
        return "Person [name=" + name + "]";
    }
    public Person(String name) {
        this.name = name;
    }
    public Person() {

    }
    public String getname() {
        return name;
    }
    public void setname(String name) {
        this.name = name;
    }
}
//测试类
package com.yc.spring;

import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class HelloTest {
    @Test
    public void testHelloStaticFactory(){
        ApplicationContext cxt=new ClassPathXmlApplicationContext("spring.xml");
        System.out.println("==========");
        Hello h01=(Hello) cxt.getBean("填写待测试的bean  id");
        System.out.println(h01);
        h01.sayHello();
        //(取到hello对象并调用sayhello方法)

    }
}

第一种方式:通过编写xml方式直接配置bean;
以下代码均在spring.xml的配置文件中编写:

<!-- xml方式配置bean  -->
        <bean id="per6" class="com.yc.spring.Hello">
                <property name="name" value="小满"></property>
                <property name="person" ref="per6_1"></property>
        </bean>
        <!-- 创建Hello对象,通过ref引用依赖Person 类 -->
        <bean id="per6_1" class="com.yc.spring.Person">
                <property name="name" value="小钦"></property>
        </bean>

    运行结果:我是hello的构造方法
                ==========
            com.yc.spring.Hello@1262d8c
            小满 对 小钦说你好帅!!!

第二种方式:通过工厂方式配置bean(工厂方式也就可以理解为,我们事先把我们要获获取的对象存放到工厂里,当我们要用的时候我们就直接通过加载工厂去获取我们想要的对象)
工厂方式又分为:静态工厂和实例工厂
2.1通过静态工厂方式配置bean(静态工厂,就是将我们的对象直接放在一个静态区里面,想用的时候我们可以直接调用就行)

//创建一个工厂类
package com.yc.spring;

import java.util.HashMap;
import java.util.Map;

public class HelloStaicFactory {
        private static Map<Integer, Hello> map=new HashMap<Integer, Hello>();
        static{
            map.put(1,new Hello("小有",new Person("小瑶")));
            //如果这里有多个对象要传入的话,就可以根据键来检索了
        }//将我们的对象都存放到工厂里面去,而且都是静态的,可以随时调用

        public static Hello getHello(int id){
            return map.get(id);
        }//对外提供获取接口,根据id获得对象
}

//一下是spring.xml中的代码
<!--  通过静态工厂方法来配置bean,注意不是配置静态工厂方法实例,而是配置bean实例 
       class属性:指向静态工厂方法的全类名
      factory-method:指向静态工厂方法的名字
      constructor-arg:如果静态工厂方法需要传入参数,则使用constructor-arg来配置参数
  -->
     <bean id="per1" class="com.yc.spring.HelloStaicFactory" factory-method="getHello">
      <constructor-arg value="1"></constructor-arg>           
    </bean>

    //测试结果:
    ==========
    com.yc.spring.Hello@17864c4
    小有 对 小瑶说你好帅!!!

2.2通过实例工厂方式配置bean,实例工厂与静态工厂的区别在于一个是静态的,可直接调用的,一个是需要先实例化工厂,在获取工厂里面的对象的

package com.yc.spring;
import java.util.HashMap;
import java.util.Map;
public class HelloInstanceFactory {
        private  Map<Integer, Hello> map;       
            public HelloInstanceFactory(){
                map=new HashMap<Integer, Hello>();
                map.put(4, new Hello("小桥",new Person("小跻")));               
            }
            public Hello getHello(int id){
                return map.get(id);
            }
}

//一下是spring.xml文件代码
<!-- 22通过实例工厂方法来配置bean 
         factory-bean:指向实例工厂方法的bean
         factory-method:指向实例工厂方法的名字
        constructor-arg:如果实例工厂方法需要传入参数,则使用constructor-arg来配置参数
     -->     
         <bean id="personFactory" class="com.yc.spring.HelloInstanceFactory"></bean>
            <bean id="per4" factory-bean="personFactory" factory-method="getHello">
         <constructor-arg value="4"></constructor-arg>
          </bean> 

运行结果:我是hello的构造方法
        ==========
        com.yc.spring.Hello@5d53c3
        小桥 对 小跻说你好帅!!!

2.3通过实现factoryBean方法来配置bean–(小编是在不想分太多类了,就勉强加载工厂这里面了,望见谅)

package com.yc.spring;

import org.springframework.beans.factory.FactoryBean;
//通过实现FactoryBean 接口
public class HelloFactoryBean  implements FactoryBean<Hello>{
    private int id;//讲道理,我现在还没理解这个id是干嘛用的,等博主知道之后再来修改,大家可自动忽略这里
    public void setId(int id) {
        this.id = id;
    }
    @Override
    public Hello getObject() throws Exception {
            return new Hello("小发",new Person("小荣"));
    }
    @Override
    public Class<?> getObjectType() {
            return Person.class;
    }
    @Override
    public boolean isSingleton() {  //选择是否只调用一次构造函数,也就是多个对象的地址是否相同
        return true;
    }

}
    //一下是spring.xml中的代码
    <!--2-3  通过实现FactoryBean方法来配置bean
         通过Factorybean来配置bean的实例
            class:指向Factorybean的全类名
           property:配置Factorybean的属性
         但实际返回的实例却是Factorybean的getObject()方法返回的实例
     -->
    <bean id="per5" class="com.yc.spring.HelloFactoryBean">
        <property name="id" value="1"></property>
    </bean>
运行结果:
    我是hello的构造方法
    ==========
    com.yc.spring.Hello@1262d8c
    小发 对 小荣说你好帅!!!

第三种方式:通过注解方式(也是目前使用非常广泛的一种,至少我觉得比以上方便多了)

package com.yc.spring;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;

@Component("hello")
//@component(把普通pojo实例化到spring容器中,相当于配置文件中的<bean id="hello" class="com.yc.spring.Hello"/>)
@Scope("prototype")//原型对象,默认为单例对象,选择会执行几次构造函数。这里选择是,每次获取新对象都会执行一次构造函数,对象地址都不同。
public class Hello {
        private String name="小丹";
        @Autowired//自动注入对象,这个注解就是spring可以自动帮你把bean里面引用的对象的bean,相当于ref的作用
        private Person person;
        public Hello() {
            System.out.println("我是hello的构造方法");
        }
        public String getName() {
            return name;
        }
        public void setName(String name) {
            this.name = name;
        }

        public Person getPerson() {
            return person;
        }

        public void setPerson(Person person) {
            this.person = person;
        }

        public void sayHello(){
            System.out.println(String.format("%s 对 %s说你好帅!!!",name,person.getname()));
        }   
}

package com.yc.spring;

import org.springframework.stereotype.Component;

@Component("person")//将person对象也加载到spring容器类
public class Person {
        String name="小州";       
        @Override
        public String toString() {
            return "Person [name=" + name + "]";
        }       
        public Person(String name) {
            super();
            this.name = name;
        }
        public Person() {

        }

        public String getname() {
            return name;
        }

        public void setname(String name) {
            this.name = name;
        }

}
//以下为spring.xml中代码
<!-- bean就由spring容器创建好的对象 -->
    <!-- 指定可以做为spring容器管理的对象的包 -->
    <context:component-scan base-package="com.yc.spring"/>

运行结果:
我是hello的构造方法
com.yc.spring.Hello@d5ba3a
小丹 对 小州说你好帅!!!

以上即为配置bean的三种方式,个人感觉注解的最为轻松,不过以后可能还是根据项目需求来嘛,该篇博客也会在日后再做完善,想了解,注解方式配置Bean的原理,请继续关注下篇博客:
自定义spring–简单了解注解配置Bean原理。

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值