2019-04-23 17:32:16 +0000   |     java spring gradle dependency injection   |   Viewed times   |    

摘要

2.2 Annotation自动装配的例子

代码地址:https://github.com/helloShen/spring-in-action-4th-edition-demo/tree/master/ch02

annotation_autowired_22包结构如下,

└── src
    ├── main
    │   └── java
    │       └── com
    │           └── ciaoshen
    │               └── sia4
    │                   └── ch02
    │                       └── annotation_autowired_22
    │                           └── soundsystem
    │                               ├── CDPlayerConfig.java
    │                               ├── CompactDisc.java
    │                               └── SixPense.java
    └── test
        └── java
            └── com
                └── ciaoshen
                    └── sia4
                        └── ch02
                            └── annotation_autowired_22
                                └── soundsystem
                                    └── CDPlayerTest.java

自动装备关键靠spring-context包下的@Configuration@ComponentScan注解。bean组件比如SixPense类先用@Component注解标注。然后@ComponentScan注解开启bean组件自动扫描,专门查找并实例化被@Component注解标注过的组件。

测试类CDPlayerTest配置context时用@ContextConfiguration给出@ContextConfiguration(classes=CDPlayerConfig.class)配置类名称。要运行CDPlayerTest测试类,可以用JUnit的@RunWith注解标注,gradle的build任务会自动运行测试。注意这里用到的Runner是spring-test包下的SpringJUnit4ClassRunner

2.2 XML自动装配的例子

尝试用XML文件来启动spring的组件自动扫描功能。

代码地址: https://github.com/helloShen/spring-in-action-4th-edition-demo/tree/master/ch02

xml_autowired_22包结构如下,

└── src
    ├── main
    │   ├── java
    │   │   └── com
    │   │       └── ciaoshen
    │   │           └── sia4
    │   │               └── ch02
    │   │                   └── xml_autowired_22
    │   │                       └── soundsystem
    │   │                           ├── CompactDisc.java
    │   │                           └── SixPense.java
    │   └── resources
    │       ├── application.properties
    │       └── xml_autowired_22
    │           └── soundsystem.xml
    └── test
        └── java
            └── com
                └── ciaoshen
                    └── sia4
                        └── ch02
                            └── xml_autowired_22
                                └── soundsystem
                                    └── CDPlayerTest.java

annotation_autowired_22的做法类似,bean组件也要用@Component注解标注。只是配置类soundsystem/CDPlayerConfig.java改成src/main/resources/包下的soundsystem.xml配置类。在里面用<context:component-scan>标签替代@ComponentScan标签。

XML配置文件soundsystem.xml放在src/main/resources/目录下,这个路径默认包含在gradle的sourceSets.main.runtimeClasspath路径集合里,很方便找。为了不搞混,增设了xml_autowired_22一级子目录。

XML配置的话,@ContextConfiguration注解属性要改成@ContextConfiguration("classpath:/xml_autowired_22/soundsystem.xml")XML配置文件的路径。注意路径前要加上classpath:前缀。

2.3 JavaConfig手动装配的例子

代码地址:https://github.com/helloShen/spring-in-action-4th-edition-demo/tree/master/ch02

javaconfig_23包结构如下,

└── src
    ├── main
    │   └── java
    │       └── com
    │           └── ciaoshen
    │               └── sia4
    │                   └── ch02
    │                       └── javaconfig_23
    │                           └── soundsystem
    │                               ├── CDPlayer.java
    │                               ├── CDPlayerConfig.java
    │                               ├── CompactDisc.java
    │                               ├── MyOldClassmate.java
    │                               └── SixPense.java
    └── test
        └── java
            └── com
                └── ciaoshen
                    └── sia4
                        └── ch02
                            └── javaconfig_23
                                └── soundsystem
                                    └── CDPlayerTest.java

之前负责自动装备的@Component@ComponentScan注解全部去掉。改为在CDPlayerConfig里用@Bean注解直接注册bean组件。声明的时候,还可以带上name属性,方便在出现多个同类型bean组件的时候指定特定的bean。

注册完bean组件之后,同样在CDPlayerTest测试类里加上@Autowired标签以智能装配合适的bean组件。

像下面这种方式引用其他的bean是一种优良实践。spring会自动推断compactDisc合适的实例。并且不会反复调用CompactDisc类的构造器,spring装配的始终是上下文中的那个bean单例。

@Bean
public CDPlayer cdPlayer(CompactDisc compactDisc) { // spring会推断出合适的bean来装配
    return new CDPlayer(compactDisc);
}

还有像下面这种方式获得的也是bean单例,

@Bean
public CompactDisc sixPense() {
    return new SixPense();
}

@Bean
public CDPlayer cdPlayer() {
    return new CDPlayer(sixPense()); // spring拦截对SixPense()构造函数的调用,始终返回单例。
}

参考文献