曾经XML的配置:
<bean id="accountService" class="com.wcgxy.domain.User" scope="" init-method="" destroy-method="">
<property name="" value="" | ref=""></property>
</bean>
用于创建对象的
他们的作用就和在XML配置文件中编写一个标签实现的功能是一样的
Component:
作用:用于把当前类对象存入spring容器中
属性:
value:用于指定bean的id。当我们不写时,它的默认值是当前类名,且首字母改小写。
Controller:
一般用在表现层
Service:
一般用在业务层
Repository:
一般用在持久层
以上三个注解他们的作用和属性与Component几乎是一模一样。
他们三个是spring框架为我们提供明确的三层使用的注解,使我们的三层对象更加清晰。
用于注入数据的
他们的作用就和在xml配置文件中的bean标签中写一个标签的作用是一样的
Autowired:
作用:自动按照类型注入。只要容器中有唯一的一个bean对象类型和要注入的变量类型匹配,就可以注入成功
如果ioc容器中没有任何bean的类型和要注入的变量类型匹配,则报错。
如果Ioc容器中有多个类型匹配时,把当前变量的名称当做id去容器里面匹配
出现位置:
可以是变量上,也可以是方法上
细节:
在使用注解注入时,set方法就不是必须的了。
Qualifier:
作用:在按照类中注入的基础之上再按照名称注入。它在给类成员注入时不能单独使用。但是在给方法参数注入时可以
属性:
value:用于指定注入bean的id。
Resource
作用:直接按照bean的id注入。它可以独立使用
属性:
name:用于指定bean的id。
以上三个注入都只能注入其他bean类型的数据,而基本类型和String类型无法使用上述注解实现。
另外,集合类型的注入只能通过XML来实现。
Value
作用:通过注解将常量、配置文件中的值、其他bean的属性值注入到变量中,作为变量的初始值。
- 常量的注入在括号里面直接写明@Value()
- bean属性、系统属性、表达式注入@Value("#{}")
- 配置文件属性注入@Value("${}")
用于改变作用范围的
他们的作用就和在bean标签中使用scope属性实现的功能是一样的
Scope
作用:用于指定bean的作用范围
属性:
value:指定范围的取值。常用取值:singleton prototype
和生命周期相关 了解
他们的作用就和在bean标签中使用init-method和destroy-methode的作用是一样的
PreDestroy
作用:用于指定销毁方法
PostConstruct
作用:用于指定初始化方法
一些其它的注解
Configuration
作用:指定当前类是一个配置类,相当于是替换了spring.xml
ComponentScan
作用:用于通过注解指定spring创建容器时要扫描的包
属性:value
它和basePackages的作用是一样的,指定要扫描的包
等同于xml中的
<context:component-scan base-package="com.wcgxy"></context:component-scan>
Bean
作用:用于把当前方法的返回值作为bean对象存入spring的ioc容器中,这样当我们类中有需要注入的参数时,就可以用Autowired自动去容器里面匹配。
属性:
name:用于指定bean的id,当不写时,默认值是当前方法的名称
细节:
当我们使用注解配置方法时,如果方法有参,spring框架会去容器中查找有没有可以匹配的bean对象,
查找方式和Autowired注解的作用一样的
Import
作用:用于导入其它配置类
属性:
value:用于指定其它配置类的字节码,当我们使用Import的注解之后,有Import注解的类就是父配置类,而导入的都是子配置类
PropertySource
作用:用于指定properties文件的位置
属性:value 指定文件的名称和路径
关键字:classpath,标识类路径下
以dbutils里的QueryRunner为例。QueryRunner创建对象时构造函数需要一个数据源,我们可以使用这些注解替换spring.xml
jdbcConfig.properties:
jdbc.driver = com.mysql.jdbc.Driver
jdbc.url = jdbc:mysql://localhost:3306/account?serverTimezone=GMT%2B8
jdbc.username = root
jdbc.password = 123456
主配置类
/**
* 该类是一个配置类,它的作用和bean.xml一样的
*/
@Configuration
@Import(JdbcConfig.class)
@ComponentScan("com.wcgxy")
@PropertySource("classpath:jdbcConfig.properties")
public class SpringConfiguration {
}
子配置类
**
* 和spring连接数据库的相关配置
*/
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;
/**
* 用于创建一个QueryRunner对象
* @param dataSource
* @return
*/
@Bean("runner")
public QueryRunner createQueryRunner(DataSource dataSource){
return new QueryRunner(dataSource);
}
/**
* 创建一个DataSource数据源对象
* @return
*/
@Bean("dataSource")
public DataSource createDataSource(){
ComboPooledDataSource ds = new ComboPooledDataSource();
try {
ds.setDriverClass(driver);
ds.setJdbcUrl(url);
ds.setUser(username);
ds.setPassword(password);
} catch (PropertyVetoException e) {
e.printStackTrace();
}
return ds;
}
}
细节
当我们使用了配置类的方式,之前获取容器的实现类就不行了,所以测试类里面做出相应的改进
//获取spring容器
//ApplicationContext ac = new ClassPathXmlApplicationContext("spring.xml");
ApplicationContext ac = new AnnotationConfigApplicationContext(SpringConfiguration.class);
//创建对象
IAccountService service = ac.getBean("accountService", IAccountService.class);
当我们在AnnotationConfigApplicationContext(SpringConfiguration.class) 里面传入了配置类的字节码后,配置类中@Configuration可以忽略不写。
另外我们也可以使用spring整合junit的注解来替换获取容器和创建对象的代码(坐标:spring-test)
Runwith
使用junit提供的一个注解把原有的main方法替换了,替换成spring提供的
ContextConfiguration
告知spring的运行器,spring的ioc创建是基于xml还是注解的,并且说明位置
属性:
locations:指定xml文件的位置,加上classpath关键字,表示在类路劲下。
classes:指定注解所在的位置
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = SpringConfiguration.class)
public class AccountServiceTest {
/*获取spring容器
//ApplicationContext ac = new ClassPathXmlApplicationContext("spring.xml");
ApplicationContext ac = new AnnotationConfigApplicationContext(SpringConfiguration.class);
//创建对象
IAccountService service = ac.getBean("accountService", IAccountService.class);*/
@Autowired()
IAccountService service = null;
@Test
public void testFindAll(){
List<Account> accounts = service.findAllAccount();
for (Account account : accounts) {
System.out.println(account);
}
}
因为我们已经用@Service(“accountService”)对service注入过,所以Autowired就可以自动匹配。