Spring-Bean配置相关

最近为了提高自己开始学习spring框架,方便自己以后查询。
第一次写公开博客,排版辣鸡实非我意,善用Ctrl+F

配置bean

通过xml文件中的bean节点来配置bean:

<!--构造类名配置bean-->
<bean   id="helloWorld" class="com.one.spring.beans.HelloWorld">
        <property name="name" value="Spring"></property>
</bean>

<!--构造方法配置bean-->
    <bean id="car" class="com.one.spring.beans.Car">
        <constructor-arg value="Audi"></constructor-arg>
        <constructor-arg value="Shanghai"></constructor-arg>
        <constructor-arg value="300000"></constructor-arg>
    </bean>

自定类:

public class HelloWorld {
    private String name;

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

    public void hello(){
        System.out.println(name);
    }
}

public class Car {
    private String brand;
    private String corp;
    private double price;
    private int maxSpeed;

    public Car(String brand, String corp, double price) {
        this.brand = brand;
        this.corp = corp;
        this.price = price;
    }

    @Override
    public String toString() {
        return "Car{" +
                "brand='" + brand + '\'' +
                ", corp='" + corp + '\'' +
                ", price=" + price +
                ", maxSpeed=" + maxSpeed +
                '}';
    }
}

main:

        //1.创建Spring的IOC容器对象
        ApplicationContext ctx=new ClassPathXmlApplicationContext("spring-config.xml");
        //2.从IOC容器中l利用id获取Bean实例
        HelloWorld helloWorld=(HelloWorld)ctx.getBean("helloWorld");
        //3.调用hello方法
        helloWorld.hello();

        //利用类型返回IOC容器中的Bean,但要求IOC容器中只有一个该类型的Bean
        Car car=ctx.getBean(Car.class);
        System.out.println(car);

通过全类名配置:
class属性:bean的全类名,通过反射方式在IOC容器中创建Bean,要求一定要有一个无参的构造器。
id属性:标识容器中的bean,id唯一。

在IOC容器读取Bean配置创建Bean实例之前,必须对容器进行实例化,只有容器实例化之后,才可以从IOC容器里获取Bean实例并使用。

Spring提供了两种类型的IOC容器实现:
1.BeanFactory:IOC容器的基本实现。
2.ApplicationContext:提供了更多的高级特性,是BeanFactory的子接口,BeanFactory是Spring框架的基础设施,面向Spring本身,ApplicationContext面向使用Spring框架的开发者,几乎所有的场合都直接使用ApplicationContext。
3.ApplicationContext有两个主要实现类。
ClassPathXmlApplicationContext:从类路径下加载配置文件。
FileSystemXmlApplicaitionContext:从文件系统中加载配置文件。
ConfigurableApplicationContext扩展于ApplicationContext,新增两个主要方法,refresh()和close(),让Application具有启动、刷新和关闭上下文的能力。

依赖注入的方式:
1.属性注入:
属性注入即通过setter方法注入Bean的属性值或依赖的对象
使用元素,使用name属性指定Bean的属性名称,value属性或子节点指定属性值
属性注入使实际应用中最常用的注入方式

<bean   id="helloWorld" class="com.one.spring.beans.HelloWorld">
        <property name="name" value="Spring"></property>
</bean>

2.构造器注入:
通过构造方法注入Bean的属性值或依赖对象,它保证了Bean实例在实例化之后就可以使用。
构造器注入在元素里声明属性,中没有name属性。

<!--构造方法配置bean-->
    <bean id="car" class="com.one.spring.beans.Car">
        <constructor-arg value="Audi"></constructor-arg>
        <constructor-arg value="Shanghai"></constructor-arg>
        <constructor-arg value="300000"></constructor-arg>
    </bean>

构造器注入可以通过中的index属性来声明注入顺序,也可以使用type属性来声明注入的数据类型,如:

<bean id="car" class="com.one.spring.beans.Car">
        <constructor-arg value="Audi" index="0"></constructor-arg>
        <constructor-arg value="Shanghai" index="1"></constructor-arg>
        <constructor-arg value="300000.0" type="double"></constructor-arg>
    </bean>

拥有多个含参构造器时,可以通过同时设置index和type属性来确定注入哪个构造器。

3.工厂方法注入(很少使用,不推荐):
(1)静态工厂方法:
调用静态工厂方法创建Bean是将对象创建的过程封装到静态方法中,当客户端需要对象时,只需要简单的调用静态方法,而不用关心创建对象的细节。
要声明通过静态方法创建的Bean,需要在Bean的class属性里指定拥有该工厂方法的类,同时在factory-method属性里指定工厂方法的名称,最后使用元素为该方法传递方法参数。

静态工厂方法类
public class StaticCarFactory {
    private static Map<String,Car> cars=new HashMap<String, Car>();

    static {
        cars.put("audi",new Car("audi",300000));
        cars.put("ford",new Car("ford",400000));
    }

    public static Car getCar(String name){
        return cars.get(name);
    }
}
-------------------------------------------------------------------------------------------------------------------------------------------------
Bean配置文件

   <!--通过静态工厂方法来配置bean,注意不是配置静态工厂方法实例,而是配置bean实例-->
   <!--
    class属性:指向静态工厂方法的全类名
    factory-method属性:志向静态工厂方法的名字
    constructor-arg:如果工厂方法需要传入参数,则使用constructor-arg来配置参数
   -->
    <bean id="car1" class="com.one.spring.factory.StaticCarFactory"
          factory-method="getCar">
        <constructor-arg value="audi"></constructor-arg>
    </bean>

(2)实例工厂方法:
将对象创建过程封装到另外一个对象实例的方法里,当客户端需要请求对象时,只需要简单的调用该实例方法而不需要关心对象创建的细节。
要声明通过实例工厂方法创建的Bean
-在Bean的factory-bean属性里指定拥有该工厂方法的bean
-在factory-method属性里指定该工厂方法的名称
-使用constructo-arg元素为工厂方法传递参数

工厂实例
public class InstanceCarFactory {
    private Map<String,Car> cars=null;

    public InstanceCarFactory(){
        cars=new HashMap<String, Car>();
        cars.put("audi",new Car("audi",300000));
        cars.put("ford",new Car("ford",400000));
    }

    public Car getCar(String brand){
        return cars.get(brand);
    }
}
--------------------------------------------------------------------------
bean配置文件

    <!--配置工厂的实例-->
    <bean id="cars" class="com.one.spring.factory.InstanceCarFactory"></bean>

    <!--通过实例工厂方法来配置bean-->
    <bean id="car2" factory-bean="cars" factory-method="getCar">
        <constructor-arg value="ford"></constructor-arg>
    </bean>

两个方法最大的区别是,一个不创建工厂方法实例,直接配置bean实例;一个必须先配置工厂方法实例,然后再配置bean实例。

FactoryBean方法:
FactoryBean类:

public class CarFactoryBean implements FactoryBean<Car> {

    private String brand;

    public void setBrand(String brand) {
        this.brand = brand;
    }

    @Override
    public Car getObject() throws Exception{
        return new Car(brand,500000);
    }

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

    @Override
    public boolean isSingleton(){
        return true;
    }
}

XML文件:

    <!--
    通过FactoryBean来配置Bean的实例
    class:指向FactoryBean的全类名
    property:配置FactoryBean的属性

    但实际返回的实例却是FactoryBean的getObject()方法返回的实例
    -->

    <bean id="car" class="com.one.spring.factorybean.CarFactoryBean">
        <property name="brand" value="BMW"></property>
    </bean>
</beans>

注入属性值的细节:

字面值:
即可以用字符串表示的值,可以通过元素标签或value属性进行注入
1.基本数据类型及其封装类,String等类型都可以采取字面值注入方式。
2.如果字面值包含特殊字符,可以使用<![CDATA[ ]]>包裹起来,例

 <constructor-arg>
 <value><![CDATA[<Shanghai>]]></value>
 </constructor-arg>

引用其他的Bean:
组成应用程序的Bean经常需要互相协作以完成应用程序的功能,要使Bean能够互相访问,就必须在配置文件中指定Bean的引用
1.可以使用property的ref 属性/元素 建立Bean之间的引用关系,例

<bean id="person" class="com.one.spring.beans.Person">
        <property name="name" value="Tom"></property>
        <property name="age" value="24"></property>
        <property name="car" ref="car"></property>
    </bean>

2.也可以在属性或者构造器里包含Bean的声明,这样的Bean称为内部Bean,例

  <bean id="person2" class="com.one.spring.beans.Person">
        <property name="name" value="Tom"></property>
        <property name="age" value="24"></property>
        <property name="car">
            <bean class="com.one.spring.beans.Car">
                <property name="brand" value="Ford"></property>
                <property name="corp" value="changan"></property>
                <property name="price" value="200000"></property>
            </bean>
        </property>
    </bean>

内部Bean不能够被外部引用,只能在内部使用,因此可以省去内部Bean的id属性。

注入参数详解:null值和级联属性
1.可以使用专用的元素标签为Bean的字符串或其他对象类型的属性注入null值
2.和Struts、Hiberante等框架一样,Spring支持级联属性的配置

    <bean id="person" class="com.one.spring.beans.Person">
        <property name="name" value="Tom"></property>
        <property name="age" value="24"></property>
        <property name="car" ref="car"></property>
          <property name="car.maxSpeed" value="180"></property>//此处为级联属性赋值
    </bean>

需要注意的是,属性需要先初始化后才可以为级联属性赋值,否则会有异常,和Struct2不同。

集合属性
1.在Spring中可以通过一组内置的xml标签,例如,或来配置集合属性:

以List为例:
外部引用

<bean id="person3" class="com.one.spring.bean.collection.Person">
        <property name="name" value="Mike"></property>
        <property name="age" value="27"></property>
        <property name="cars">
            <list>
                <ref bean="car1"/>
                <ref bean="car1"/>
                <ref bean="car1"/>
            </list>
        </property>
    </bean>

需要注意的是,ref引用的bean必须在同一个java包下。

内部Bean:

    <bean id="person3" class="com.one.spring.bean.collection.Person">
        <property name="name" value="Mike"></property>
        <property name="age" value="27"></property>
        <property name="cars">
            <list>
                <bean class="com.one.spring.bean.collection.Car">
                    <!--属性注入-->
                </bean>

                <bean class="com.one.spring.bean.collection.Car">
                    <!--属性注入-->
                </bean>
            </list>
        </property>
    </bean>

set和数组与list相似,不作额外记录。

Map:
通过标签定义,标签中可以使用多个作为子标签,每个条目包含一个键和一个值。

    <bean id="newPerson" class="com.one.spring.bean.collection.NewPerson">
        <property name="name" value="rose"></property>
        <property name="age" value="28"></property>
        <property name="carMap">
            <map>
                <entry key="AA" value-ref="car1"></entry>
                <entry key="AB" value-ref="car"></entry>
            </map>
        </property>
    </bean>

使用定义 ,该标签使用多个作为子标签,每个标签必须定义key属性:
可作为连接数据库的配置文件


    <bean id="student" class="com.one.spring.beans.DataSource">
        <property name="name" value="a"></property>
        <property name="age" value="18"></property>
        <property name="properties">
            <props>
                <prop key="username">xx</prop>
                <prop key="password">xx</prop>
                <prop key="driverclass">xx</prop>
                <prop key="url">xx</prop>
            </props>
        </property>
    </bean>

使用util配置独立的集合Bean,方便被多个Bean引用

   <util:list id="cars">
        <ref bean="car1"/>
        <ref bean="car"/>
    </util:list>

    <bean id="person3" class="com.one.spring.bean.collection.Person">
        <property name="name" value="Mike"></property>
        <property name="age" value="27"></property>
        <property name="cars" ref="cars"> </property>
    </bean>

使用P命名空间:
为了简化xml文件的配置,越来越多的xml文件采用属性而费子元素配置信息。
P命名空间可以通过元素属性的方式配置Bean的属性。使用P命名空间后,基于XML的配置方式将进一步简化

<bean id="person5" class="com.one.spring.bean.collection.Person" p:age="12" p:name="test"  p:cars-ref="car1"></bean>

自动装配:
使用自动装配来配置Bean

<bean id="address" class="com.one.spring.autowire.Address" p:city="BJ" p:street="HLG"/>
    <bean id="car6" class="com.one.spring.autowire.Car" p:brand="Audi" p:price="300000"/>
    <!--
    可以使用autowire来指定自动装配的方式
    byName 根据bean的名字和当前bean的setter方法属性名进行自动装配,若没有匹配的属性名,则为null
    byType 根据bean的类型和当前bean的属性的类型进行自动装配,若有多个同类型属性,则抛出异常
    -->
    <bean id="person" class="com.one.spring.autowire.Person" p:name="Tom" autowire="byName"/>
</beans>

自动装配时,不能单独装配个别属性,不够灵活。

Spring-Bean之间的关系

1.继承
可以使用parent属性来继承大部分属性

    <bean id="address" class="com.one.spring.autowire.Address" p:city="BJ" p:street="WDK"/>
    <bean id="address2" parent="address" p:street="DZS"/>

可以使用abstract元素来让bean成为一个纯粹的只能被继承的bean:

    <bean id="address3"  abstract="true">
        <property name="city" value="123"/>
        <property name="street" value="321"/>
    </bean>
    <bean id="address4" class="com.one.spring.autowire.Address" parent="address3" p:city="312"/>

学习的时候,抽象bean中是可以使用p命名空间来进行属性注入的,我反复尝试了许多次都失败了,最后发现可以用依赖注入来代替

2.依赖关系:
Spring允许用户通过depends-on属性设定并前置依赖的Bean,前置依赖的Bean会在本Bean实例化之前创建好。如果前置依赖于多个Bean,则可以通过逗号,空格的方式配置Bean的名称。

    <!--构造方法配置bean-->
    <bean id="car" class="com.one.spring.beans.Car">
        <constructor-arg value="Audi" index="1"></constructor-arg>
        <constructor-arg value="Shanghai" index="0"></constructor-arg>
        <constructor-arg value="300000" index="2"></constructor-arg>
    </bean>

    <!--要求在配置Person时必须要有一个关联的car,换句话说,依赖于car-->
    <bean id="person" class="com.one.spring.autowire.Person" p:name="Tom" p:address-ref="address4" depends-on="car"/>

Bean的作用域:
利用bean的scope属性来配置bean的作用于
singleton:默认值,容器初始创建bean实例,在整个容器的生命周期内只创建这一个bean,单例的。
prototype:原型的,容器初始化时不创建bean的实例,而在每次请求时都创建一个新的Bean实例,并返回。

    <bean id="car" class="com.one.spring.autowire.Car"
          scope="singleton">
        <property name="brand" value="Audi"/>
        <property name="price" value="20000"/>
    </bean>

Spring使用外部属性文件:
在配置文件里配置Bean时,有时需要在Bean的配置里混入系统部署的细节信息,如文件路径,数据源配置信息等,这些部署实际上需要和Bean配置分离。
Spring提供了一个PropertyPlaceholderConfigurer的BeanFactory后置处理器,这个处理器允许用户将Bean配置的部分内容外移到属性文件中,可以在Bean配置文件里使用形式为${brand}的变量,PropertyPlaceholderConfigurer从属性文件里加载属性,并使用这些属性来替换变量。

    <context:property-placeholder location="classpath:db.properties"/>

    <bean id="car" class="com.one.spring.autowire.Car">
        <property name="brand" value="${brand}"/>
    </bean>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值