首先我们来回顾一下在bean.xml中的配置文件,这里我们想通过java实现类的方式,替代我们的bean.xml,也就是用注解的方式来完成配置。
bean.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"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">
<bean id="accountService" class="com.ysw.web.service.impl.AccountServiceImpl">
<property name="accountDao" ref="accountDao"></property>
</bean>
<bean id="accountDao" class="com.ysw.web.dao.impl.AccountDaoImpl">
<property name="runner" ref="runner"></property>
</bean>
<context:component-scan base-package="com.ysw"></context:component-scan>
这个在创建好对象之后是会自动放到SpringIoC容器中的
<bean id="runner" scope="prototype" class="org.apache.commons.dbutils.QueryRunner">
<!--注入数据源-->
<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:///account"></property>
<property name="user" value="root"></property>
<property name="password" value="123456"></property>
</bean>
</beans>
这里,倘若我们想用Spring-IoC容器中的注解方式来替代这个xml文件的话,我们首先要使用第一个注解关键字:
@Configuration
作用:通过这个注解关键字的使用,可以把我们当前的全限定类名作为一个配置文件,也就是变成一个配置类。
@ComponentScan(“ ”)
功能类似于: <context:component-scan base-package="com.ysw"></context:component-scan>这个标签
作用:回顾一下在我们bean.xml中,我们倘若使用了注解在java类中使用了注解的话,我们是要对我们所有的package包进行扫描操作的。这里ComponentScan的作用就是扫描我们指定的包下的所有内容,也就是通过注解的方式指定Spring在创建核心容器的时候需要扫描的包。我们来查看一下底层的源码:
@AliasFor("basePackages")
String[] value() default {};
@AliasFor("value")
String[] basePackages() default {};
这里我们可以很明显的看到,底层源码使用了@AliasFor注解,这个注解主要是用于起别名的操作,并且这里有两个可以使用的参数,一个是basePackages,另一个是value,其实使用的时候它们都是一样的。
@Bean / @Bean(name = " ")
在完成了以上的配置之后,由于我们还没有把我们所配置好的对象存入Spring-IoC核心容器中去,所以这里我们需要使用一个@Bean的注解把我们当前生成的对象放入Spring核心容器。一般来说,这个@Bean注解默认我们的方法名是唯一id,方法返回值作为我们的value值,通过key-value键值对的方式存入Spring-IoC核心容器。如果说用户想自定义id的话就可以直接加一个name进Bean注解。
注意:如果我们的方法中有参数的话,这个参数是会在我们的Spring核心容器中,通过与@Autowired相同的匹配方式来进行自动注入的。如果说接口类型相同并且id唯一的话就会直接匹配,如果说接口类型相同但是id不唯一的话,就可以通过参数对象名的方式来进行id的唯一匹配操作,否则是会报错的。
替换bean.xml后我们的java类配置文件代码如下:
package config;
import com.mchange.v2.c3p0.ComboPooledDataSource;
import org.apache.commons.dbutils.QueryRunner;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Scope;
import javax.sql.DataSource;
/**
* 该类是一个配置类,作用跟bean.xml是一样的
*
* Spring中的新注解
* @Configuration
* 作用:指定当前类是一个配置类
*
* @ComponentScan
* 作用:用于通过注解指定Spring在创建容器时要扫描的包
* 属性:
* value:作用是和basePackage的作用都是一样的,
* 都是用于指定创建容器时要扫描的包。
* <context:component-scan base-package="com.ysw">
* </context:component-scan>
*
* @Bean
* 作用:用于把当前方法的返回值作为对象存入SpringIoC容器中
* 注解的属性:
* name:用于指定bean的id。
* 当不写时默认值是当前方法的名称
* value:返回值创建的对象就是value
*
* 细节:
* 如果我们使用注解配置方法时,如果方法有参数,
* Spring框架会自动去容器中查找有没有可用的bean对象
* 查找的方式跟Autowired注解的作用是一样的
* 匹配唯一类型的时候就直接注入,如果没有就报错
* 如果有多个匹配时,就根据id进行匹配
*/
//配置类
@Configuration
//扫描包,要使用类路径,
// basePackages = {}这个是一个数组,
// 当且仅当只有一个的时候是可以不用{}的
@ComponentScan("com.ysw")
//或者使用
//@ComponentScan(value = "com.ysw")
public class SpringConfiguration {
/**
* 创建一个QueryRunner对象,但是不会自动放入Spring-IoC容器中
* 所以要用@Bean来把我们创建的对象放入Spring-IoC容器
*
* 存入SpringIoC容器时,createQueryRunner是id,
* 返回值是new QueryRunner(dataSource)是value
*
* 当然也可以写id名
* @param dataSource
* @return
*/
@Bean(name = "runner")
//设置为多例的
@Scope("prototype")
public QueryRunner createQueryRunner(DataSource dataSource){
//这个方法相当于是实例化创建一个QueryRunner对象,并且传入参数dataSource到构造函数中去
//QueryRunner queryRunner = new QueryRunner(dataSource);
return new QueryRunner(dataSource);
}
/**
* 创建数据源对象
* @return
*/
@Bean(name = "dataSource")
public DataSource createDataSource(){
try {
//这里实例化new一个对象出来进行设置
ComboPooledDataSource ds = new ComboPooledDataSource();
ds.setDriverClass("com.mysql.jdbc.Driver");
ds.setJdbcUrl("jdbc:mysql:///account");
ds.setUser("root");
ds.setPassword("123456");
return ds;
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}
调用我们这个java配置类的时候需要使用到@AnnotationConfigApplicationContext
@Test
public void findAll() {
//1、获取容器
// ApplicationContext ac = new ClassPathXmlApplicationContext("bean.xml");
ApplicationContext ac = new AnnotationConfigApplicationContext(SpringConfiguration.class);
IAccountService accountService = (IAccountService)ac.getBean("accountService");
List<Account> accounts = accountService.findAllAccount();
for (Account account : accounts) {
System.out.println(account);
}
}