Spring学习(二):3个装配bean方式

bean的生命周期

bean.jpg
  • Bean配置信息定义了Bean的实现及依赖关系,Spring容器根据各种形式的Bean配置信息在容器内部建立Bean定义注册表,然后根据注册表加载、实例化Bean,并建立Bean和Bean的依赖关系,最后将这些准备就绪的Bean放到Bean缓存池中,以供外层的应用程序进行调用。

3个装配方式

  • 基于Java类的配置方式
  • 基于XML的配置方式
  • 基于注解的配置方式

1.基于Java类的配置方式

基于Java类定义Bean配置元数据,其实就是通过Java类定义Spring配置元数据,且直接消除XML配置文件。

1.1要点:

  • 必须要两个注解:
    • @Configuration :代替了xml配置.表明该类是一个配置类,该类应该包含在Spring应用上下文中如何创建bean的细节。
    • @Bean : 告诉Spring,这个方法将会返回一个对象。一般用在构造器和Setter方法上
  • 只需要这个两个注解,就可以完成bean的装配过程了。
  • 非必须的注解:
    • @import :用来引入别的类里面同样有@Configuration标签的类。
    • @importResource : 用来引入xml配置,实现xml配置方式和java类配置方式共存。

1.2例子

  • 代码结构
    • Configuration 包:用来放Java类的配置。其实其作用就是跟xml配置一样的。所以此包下的类是Java类配置方式的核心
    • Entity 包:用来放bean
    • test 包: 测试
  • 代码
    • Configuration 包下的EntityConfig类:
@Configuration //表示这个类可以使用 Spring IoC 容器作为 bean 定义的来源
public class EntityConfig {

    @Bean
    public UserBean user(){
        return new UserBean( student());  //有参构造
    }

    @Bean
    public StudentBean student(){
        return new StudentBean();
    }
}
  • Entity 包 UserBean类和StudentBean类:
public class UserBean {
    private StudentBean studentBean;

    public UserBean(){}
    public UserBean(StudentBean studentBean){
        this.studentBean=studentBean;
    }

    @Override
    public String toString() {

        return "this is UserBean";
    }

    public StudentBean getStudent(){
        return studentBean;
    }
}
public class StudentBean {
    private String name;
    private int age;

    @Override
    public String toString() {
        return "this is StudentBean";
    }
}
  • test 包
@Test
    public void test(){
       
        ApplicationContext ctx=
                new AnnotationConfigApplicationContext(EntityConfig.class);  //应用上下问
        UserBean userBean=ctx.getBean(UserBean.class);

        StudentBean student = userBean.getStudent(); //从userBean里,看是否获得studenBean
        System.out.println(student.toString());

    }

1.3基于Java类的配置主要使用场景:

对于实例化Bean的逻辑比较复杂,则比较适合用基于Java类配置的方式

2.基于XML配置

其实可从基于java类配置方式去考虑,在Java类配置方式中,需要的两个注解@Configuration 和@Bean 转化成xml配置文件里说明。这样的话java的配置类也可以不要了。

2.1要点

2.2 例子

  • Entity类:跟上面类一样,不需要该。
  • 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-2.5.xsd">


    <bean id="studentBean" class="cn.Entity.StudentBean"/>  

    <bean id="userBean" class="cn.Entity.UserBean">
     //在userBean类里面注入StudentBean 类,如果没有这条会出现
       NullPointerException异常
    <property name="studentBean"  ref="studentBean"/>    
     // name="" 是userBean 的属性名称。(需要setter方法)
     // ref="" 是上面studentBean类注入的id。
     </bean>



</beans>
  • test类
@Test
    public void testUserBean(){
        ApplicationContext ctx=
                new ClassPathXmlApplicationContext("spring.xml"); //配置文件的绝对路径
        if (ctx!=null){
            UserBean user = (UserBean) ctx.getBean(UserBean.class);
            System.out.println(user.getStudent());
        }
    }
  • 使用场景:
    • 第三方类库,如DataSource、JdbcTemplate等;
    • 命名空间,如aop、context等;

3.自动化装配bean

可以对比前面两种方法的变化,可以知道配置方法上的不同了。

  • 相对于基于xml配置方法来说,不需要在xml里面配置注入bean的信息,而换成注解注入。
  • 而相对与基于java配置方法来说,不需要在配置类中创建对象的方法,只需要在需要注入的地方,用注解就可以了

3.1要点

  • 从两个角度来实现自动化装配:
    • 组件扫描:Spring会自动发现应用上下文中所创建的bean。(需要在xml里面配置,或者用注解)
    • 自动装配:Spring自动满足bean之间的依赖。(需要用注解)

3.2例子

  • 用@configuration来装配bean
    • 用到的注解
      • @Configuration :代替了xml配置.表明该类是一个配置类,该类应该包含在Spring应用上下文中如何创建bean的细节。
      • @ComponentScan:启动组件扫描。(如果没有设定范围,默认该包下)
      • @Autowired :自动注入。用在类下对象的注入
      • @Compoent : 表明该类会作为组件类,并告知Spring要为该类建立bean。
      • @RunWith(SpringJUnit4ClassRunner,class):在测试开始的时候自动创建Spring的应用上下文
    • @ContextConfiguration(class=xxxx) :加载配置,在这里是Config.class

很奇怪,如果不用@ContextConfiguration(class=xxxx) 这个加载配置,是扫描不到我测试类下面的@Autowired 注解。也就是我用正规创建上下文方法创建的话,test类下的对象是null的。 有待解决
- 代码结构
- Config类:用来装配Spring规则。具有@Configuration和@ComponentScan注解
- StudentBean类和UserBean
- test类
- 例子
- Config类

@Configuration
@ComponentScan(basePackages = {"cn.Entity"})
public class Config {  //不需像基于java配置一样,用方法返回new 对象。
}
  - SutdentBean和UserBean类 
@Component
public class StudentBean {
    private String name;
    private int age;

    @Override
    public String toString() {
        return "this is StudentBean";
    }
}

***********************************************************************
@Component
public class UserBean {
    private StudentBean studentBean;


    public UserBean(){}

    @Autowired
    public UserBean(StudentBean studentBean){
        this.studentBean=studentBean;
    }

    @Override
    public String toString() {

        return "this is UserBean";
    }

    public StudentBean getStudent(){
        return studentBean;
    }



    public StudentBean getStudentBean() {
        return studentBean;
    }


}

  • test类
 @RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = Config.class)
public class UserBeanTest extends TestCase {

    @Autowired
    private UserBean userBean;

    @Test
    public void testUserBean(){

            System.out.println(userBean.getStudent());
             System.out.println(userBean);

    }
}
  • 用xml配置文件来装配bean
    只是把上面的Config类,用xml替换掉。其实只是用xml文档写一个扫描语句
    • spring.xml文档
            <?xml version="1.0" encoding="UTF-8"?>
            <beans //省去很多约束
      
            <context:component-scan base-package="cn.Entity"/>
      
            </beans>
      
      
    • StudentBean类和UserBean类没变
    • Test类
              @RunWith(SpringJUnit4ClassRunner.class)
               @ContextConfiguration({"/spring.xml"})  //加载xml配置
             public class UserBeanTest extends TestCase {
                @Autowired
               private UserBean userBean;
               @Test
                 public void testUserBean(){
                       System.out.println(userBean.getStudent());
                        System.out.println(userBean);
                 }       }
      
  • 使用场景:Bean的实现类是当前项目开发的,可直接在Java类中使用注解配置

4.总结

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

推荐阅读更多精彩内容