不写 bean.xml 文件,所有配置都用注解来实现
基于注解的 IoC 配置已经完成,但还是离不开 xml 配置文件,是因为有一句很关键的配置:
<!-- 告知spring框架在,读取配置文件,创建容器时,扫描注解,依据注解创建对象,并存入容器中 -->
<context:component-scan base-package="com.fgy"></context:component-scan>
另外,数据源和 QueryRunner(JdbcTemplate)的配置也需要靠注解来实现。
<!--配置QueryRunner-->
<bean id="runner" class="org.apache.commons.dbutils.QueryRunner" scope="prototype">
<!--注入数据源-->
<constructor-arg name="ds" ref="dataSource"></constructor-arg>
</bean>
<!-- 配置数据源 -->
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<!--连接数据库的必备信息-->
<property name="driverClass" value="com.mysql.jdbc.Driver"></property>
<property name="jdbcUrl" value="jdbc:mysql://localhost:3306/spring"></property>
<property name="user" value="root"></property>
<property name="password" value="root"></property>
</bean>
需要用到注解:
@Configuration
作用:
用于指定当前类是一个 spring 配置类,当创建容器时会从该类上加载注解。
获取容器时需要使用AnnotationApplicationContext(有@Configuration 注解的类.class)。
属性:
value:用于指定配置类的字节码
@Configuration public class SpringConfiguration { }
@ComponentScan
作用:
用于指定 spring 在初始化容器时要扫描的包。作用和在 spring 的 xml 配置文件中的:
<context:component-scan base-package="com.fgy"/>是一样的。
属性:
value:用于指定要扫描的包。和 xml 中的 base-package 属性作用一样。
@Configuration @ComponentScan("com.fgy") public class SpringConfiguration { }
@Bean
作用:
该注解只能写在方法上,表明使用此方法创建一个对象返回出来,并且放入 spring 容器。
属性:
name:给当前@Bean 注解方法创建的对象指定一个名称(即 bean 的 id),如果不指定,默认值是当前方法名称。
细节:
当使用此注解配置方法时,如果方法有参数( createQueryRunner(DataSource dataSource) ),spring 框架会去容器中查找有没有可用的 bean 对象。
查找的方式和 Autowired 注解的作用是一样的
public class JdbcConfig { /** * 创建一个数据源,并存入 spring 容器中 * @return */ @Bean(name="dataSource") public DataSource createDataSource() { try { ComboPooledDataSource ds = new ComboPooledDataSource(); ds.setUser("root"); ds.setPassword("root"); ds.setDriverClass("com.mysql.jdbc.Driver"); ds.setJdbcUrl("jdbc:mysql:///spring"); return ds; } catch (Exception e) { throw new RuntimeException(e); } } /** * 创建一个 QueryRunner,并且也存入 spring 容器中 * @param dataSource * @return */ @Bean(name="runner")
@Scope(prototype) public QueryRunner createQueryRunner(DataSource dataSource) { return new QueryRunner(dataSource); } }
@PropertySource
作用:
用于加载.properties 文件中的配置。例如配置数据源时,可以把连接数据库的信息写到 properties 配置文件中,
就可以使用此注解指定 properties 配置文件的位置。
属性:
value[]:用于指定 properties 文件位置。如果是在类路径下,需要写上 classpath:
@Configuration @PropertySource("classpath:jdbc.properties") public class JdbcConfig { @Value("${jdbc.driver}") private String driver; @Value("${jdbc.url}") private String url; @Value("${jdbc.username}") private String username; @Value("${jdbc.password}") private String password; /** * 创建一个数据源,并存入 spring 容器中 * @return */ @Bean(name="dataSource") public DataSource createDataSource() { try { ComboPooledDataSource ds = new ComboPooledDataSource(); ds.setDriverClass(driver); ds.setJdbcUrl(url); ds.setUser(username); ds.setPassword(password); return ds; } catch (Exception e) { throw new RuntimeException(e); } } /** * 创建一个 QueryRunner,并且也存入 spring 容器中 * @param dataSource * @return */ @Bean(name="runner") @Scope("prototype") public QueryRunner createQueryRunner(DataSource dataSource) { return new QueryRunner(dataSource); } }
jdbc.properties 文件:
jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/spring
jdbc.username=root
jdbc.password=root
@Import
作用:
用于导入其他配置类,在引入其他配置类时,可以不用再写@Configuration 注解,写上也没问题。
属性:
value[]:用于指定其他配置类的字节码。
@Configuration @ComponentScan(basePackages = "com.fgy") @Import({JdbcConfig.class}) public class SpringConfiguration { }
注意:新的问题产生了,由于没有配置文件了,如何获取容器呢?
ApplicationContext ac = new AnnotationConfigApplicationContext(SpringConfiguration.class);
工程结构图: