Spring学习系列--2.配置Bean

目录

  1. 待完善

Spring Bean

  • IOC 容器 BeanFactory 和 ApplicationContext

  • DI 方式 属性注入 和构造器注入

  • bean 配置

    • id 必须唯一
    • class 全路径,因为是通过反射来构建bean,所以bean中必须有一个无参的构造器。
  • Spring IOC 容器,必须对其进行实例化,才能从IOC容器中获取bean,Spring 提供了2种容器

    • ApplicationContext 是BeanFactory的子接口提供了更多的高级特性,面向Spring框架开发者
      • ClassPathXmlApplicationContext:从类路径下加载配置文件
      • FileSystemXmlApplicationContext:从文件系统加载配置文件
      • WebApplicationContext:基于web的
    • BeanFactory IOC 基本实现,面向Spring本身。
    • 配置是不变的。
    • ConfigurableApplicationContext 扩展了 ApplicationContext 主要增加了2个方法,refresh(),close() 让ApplicationContext具有启动、刷新和关闭上下文的能力


      image
  • ApplicationContext 在初始化的时候就初始化了所有的单例的bean

getBean

  1. 利用id
Car car1 = (Car) context.getBean("car1");
  1. 利用XXX.class 这种需要容器中类唯一,如果两个类ID不同 ,用这种方法会报错。好处是不需要再转型
UserEntity user = context.getBean(UserEntity.class);
  1. 还有一些不常用的,没有整理。

使用xml配置bean

  1. 属性注入,<property> 主要是用来注入一些字面值,比如String ,int 等
<!-- 使用property 注入car -->
    <bean id="car1" class="com.nina.spring.bean.Car">
        <property name="brand" value="Audi"></property>
        <property name="price" value="20000"></property>
    </bean>
  1. 构造方法注入, <constructor-arg> 这里主要,注入属性的个数,需要与对应bean中有参的构造器一致,否则会提示没有对应参数的构造器
<!-- 使用构造器 注入 -->
    <bean id="car2" class="com.nina.spring.bean.Car">
        <constructor-arg type="java.lang.String" value="Toyot"></constructor-arg>
        <constructor-arg type="double" value="300000"></constructor-arg>
    </bean>
  1. 如果字面值包含特殊字符可以用 <![CDATA[]]>包裹
<!-- 使用property 注入car3 -->
    <bean id="car3" class="com.nina.spring.bean.Car">
        <property name="brand">
            <value><![CDATA[<SANGTanna&&>]]></value>
        </property>
        <property name="price" value="20000"></property>
    </bean>
  1. 注入类,使用<ref>
<!-- car1 是之前的car的id ref 用来引用类 -->
    <bean id="person1" class="com.nina.spring.bean.Person">
        <property name="age" value="20"/>
        <property name="name" value="HuangSang"/>
        <property name="car" ref="car1"/>
    </bean>
  1. 还可以用使用内部bean
  2. null 值,使用 <null/>
  3. 级联属性赋值,属性需要初始化后,才可以使用级联赋值。
<bean id="person1" class="com.nina.spring.bean.Person">
        <property name="age" value="20"/>
        <property name="name" value="HuangSang"/>
        <property name="car" ref="car1"/>
        <property name="car.brand" value="MAITeng"></property>
    </bean>
  1. 集合属性 list map 需要使用 entry
<property name="carList">
            <list>
                <ref bean="car1" />
                <ref bean="car2" />
                <ref bean="car3" />
            </list>
        </property>
        <property name="carMap">
            <map>
                <entry key="AA" value-ref="car1"></entry>
                <entry key="BB" value-ref="car2"></entry>
            </map>
        </property>
  1. properties 使用 pros
    <bean id="dataSource" class="com.nina.spring.bean.DataSource">
        <property name="properties">
            <props>
                <prop key="user">root</prop>
                <prop key="pass">shordaao</prop>
            </props>
        </property>
    </bean>
  1. 配置单例的集合bean,需要导入util命名空间
<util:list id="cars">
        <ref bean="car1"/>
        <ref bean="car2"/>
    </util:list>
    
    <bean id="person2" class="com.nina.spring.bean.Person">
        <property name="carList" ref="cars"></property>
    </bean>
  1. p命名空间,需要先导入,
<bean id="person3" class="com.nina.spring.bean.Person" p:age="399" p:car-ref="car3">
    </bean>

  1. 自动装配, 在bean 的属性里面,指定autowire的模式byType,byName
<bean id="person4" class="com.nina.spring.bean.Person" autowire="byType"></bean>
  1. bean 之间的关系,继承和依赖。子bean可以继承父bean的所有属性,并可以覆盖,父bean,如果只是用作配置模板,可以指定 abstract=“true” , 这样不能实例化,同时,抽象bean,可以不指定 class 属性。
<bean id="address" class="com.nina.spring.bean.Address" p:street="wudaokou">
        <property name="city" value="Beijing"></property>
    </bean>
    
    <bean id="address2" class="com.nina.spring.bean.Address" parent="address" p:street="xihongmen"></bean>
  1. bean的作用域
scope="singleton" 默认是单例的,就是每次获得的是同一个bean,容器初始化就创建bean
 scope="prototype" 每次向容器获取bean,都会产生一个新的bean,调用时才会创建
 
  1. 使用外部属性文件,Spring 提供了一个PropertyPlaceHolderConfigurer的BeanFactory 后置处理器,这个处理器允许用户将Bean配置的部分内容移到属性文件中,可以在Bean配置中使用${var}的变量。Spring还允许属性文件中引进 ${propName},以实现属性间的相互引用。
<!-- 导入配置文件 -->
    <context:property-placeholder location="classpath:db.properties"/>
    <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
        <property name="user" value="${user}"></property>
        <property name="password" value="${password}"></property>
        <property name="driverClass" value="${driverClass}"></property>
        <property name="jdbcUrl" value="${jdbcUrl}"></property>
    </bean>
  1. 配置文件中使用Spel,spel类似于el表达式,以#{},来处理。其中可以引用字面变量,可以引用bean(id),引用属性(xx.xx),引用方法。
  2. bean的生命周期。可以有以下顺序,
  • 构造器
    
  • 设置属性
    
  • init
    
  • 返回bean
    
  • destroy
    
<bean id="car" class="com.nina.spring.bean.Car" init-method="clone" destroy-method="finalize">
<property name="brand" value="#{'SangTaNa'}"></property>
</bean>
  1. bean的后置处理器。Spring允许使用bean的后置处理器在调用初始化方法前对bean进行额外处理。需要实现接口BeanPostProcessor, 在xml配置中,只需要配置改bean的class,不需要ID,另外,这种bean 会对所有的bean在init前后进行操作。有必要在方法中进行判断
public class Tree implements BeanPostProcessor {

    public Object postProcessAfterInitialization(Object arg0, String arg1) throws BeansException {
        // TODO Auto-generated method stub
        return null;
    }

    public Object postProcessBeforeInitialization(Object arg0, String arg1) throws BeansException {
        // TODO Auto-generated method stub
        return null;
    }

}
  1. 通过静态工厂方法来配置bean,按例子,获取的bean是car1,配置的class是工厂的,标注获取的方法,factory-method,如果需要参数,则通过 constructor-arg 配置
<bean id="car1" class="com.nina.spring.factory.SimpleBeanFactory" factory-method="getCar">
        <constructor-arg value="aa"></constructor-arg>
    </bean>
  1. 通过实例工厂方法来配置bean,先需要创建工厂本身,再获取bean
  2. 通过FactoryBean,配置。
  • 自定义的FactoryBean 需要实现FactoryBean接口。配置class为factorybean,但是实际返回的是对应的getObject方法对应得实例。

基于注解的方式类配置bean

组件扫描

Spring 能够从classpath下自动扫描和实例化具有特定注解的组件

  • @Component 基本注解 标注了一个受Spring 管理的组件
  • @Respository标识持久层组件
  • @Service 标识业务层或服务层组件
  • @Controller 标识表现层组件
  1. xml中配置 需要导入context命名空间
<context:component-scan base-package="com.nina.spring"></context:component-scan>

  1. 默认的id为类名的第一个字母小写,如果有特殊要求可以使用value属性,eg.@Service(vallue="ddd"),其实可以写为(“ddd”)
  2. 可以通过 resour-pattern 指定扫描的资源

  1. 包含什么需要 use-default-filters属性配合
<context:component-scan base-package="com.nina.spring" use-default-filters="true">
        <context:exclude-filter type="annotation" expression=""/>
    </context:component-scan>
  1. 注解建立bean之间的关联关系
  • <context:component-scan>元素会自动注册 AutowireAnnotationBeanPostProcessor实例,该实例可以自动装配具有@Autowired,@Resource,@Inject注解的实例
  • @Autowired 可以自动装配具有兼容类型的单个Bean属性,可以有一个属性 required=false,就不需要强制要求容器有这个对应的bean了。
  • @Autowired 注解的属性名称,如果与bean的id不匹配,可以在bean上指定value,也可以在属性上增加注解 @Qualifier, @Qualifier还可以加到入参上面。
  • 另外两个类似
  1. 泛型依赖注入,Spring 可以为子类注入子类对应的泛型类型的成员变量引用(Spring4.0的新特性哦)
public class User implements Serializable {

    private Long id;
    private String name;
}

public class BaseService<T> {

    @Autowired
    protected BaseRepository<T> repository;
    
    public void add(){
        System.out.println("service add ...");
        System.out.println(repository);
    }
    
}

public class BaseRepository<T> {

}

@Service
public class UserService extends BaseService<User> {

}

@Repository
public class UserRepository extends BaseRepository<User> {

}

public static void main(String[] args) {
        ApplicationContext ctx = new ClassPathXmlApplicationContext("bean-generic.xml");
        UserService service = (UserService) ctx.getBean("userService");
        service.add();
    }

有关Bean的基础配置注入,暂时先告一段落。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 202,529评论 5 475
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,015评论 2 379
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 149,409评论 0 335
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,385评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,387评论 5 364
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,466评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,880评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,528评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,727评论 1 295
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,528评论 2 319
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,602评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,302评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,873评论 3 306
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,890评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,132评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,777评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,310评论 2 342

推荐阅读更多精彩内容