Spring入门(三)----基于注解的IOC配置
作者:互联网
三、基于注解的IOC配置
文章目录
概念:基于注解的IOC配置和xml配置实现的功能都是一样的。
1、xml配置的形式
对上面的xml配置进行总结,可以分为以下四个功能
- 用于创建对象
- 用于注入数据
- 用于改变作用范围
- 和生命周期相关
2、基于注解配置
3.1用于创建对象的注解
- @Component
作用:是将资源让Spring来管理,相当于xml中配置了一个bean。
属性:value:指定bean的id,如果不指定value属性,默认bean的id是当前的类名。首字母小写。
- @Controller、@Service、@Reporsitory
它们三个注解都是针对一个的衍生注解,它们的作用及属性都是一模一样的。它们只不过是提供了更加明确的语义化。
@Controller :一般用于表现层的注解
@Service:一般用于业务层的注解
@Repository:一个用于持久层的注解
note:如果注解中有且仅有一个属性要赋值时,且名称是value,value的赋值是可以不写的
3.2用于注入数据的注解
它们的作用就和xml配置文件中的bean标签中写一个标签的作用是一样的
- @AutoWired
自动按照类型注入,只要容器中有唯一的一个bean对象类型和要注入的变量类型匹配,就可以注入成功。如果IOC容器没有任何bean的类型和注入的变量类型匹配,则报错。
它可以作用在变量上,也可以作用在方法上
先在Map的Value 结构中查找数据类型匹配的,如果匹配就直接注入数据。否则在Key中查找与变量名称匹配的。
- @Qualifier
在自动按照类型注入的基础上,按照bean的id注入。它在给字段注入时不能独立使用,必须和@Autowire一起使用,但是给方法参数注入时,可以独立使用。
属性: value:指定bean的id。
@Autowired
@Qualifier("accountDao1")//查找注解为"accountDao1"的对象注解
private AccountDao accountDao;
- @Resource
直接按照bean的Id注入,它也能注入其它bean类型
属性:name:指定bean的id
@Resource(name = "accountDao2")//查找注解为"accountDao2"的对象注解
private AccountDao accountDao;
Note:@AutoWire、@Qualifier、@Resource都只能注入其它bean类型,而基本的类型和String是无法使用这三个注解实现的,集合类型的注入只通过xml来实现。
@Value
注入基本数据类型和String类型的数据
属性:value:用于指定值
3.3用于改变作用范围
@Scope
指定bean的作用范围,
属性:指定范围的值,取值为:Singleton 、prototype、request、session、globalsession
3.4和生命周期相关的
- @PostConstruct:用于指定初始化方法
- @PreDestory:用于指定销毁方法
3.5注解和xml的比较及选择
注解:配置简单,维护方便(我们找到了类,就相当于找到了对应的位置)
xml:修改时,不需要改动源码,不涉及重新编译和部署
基于XML的配置 | 基于注解的配置 | |
---|---|---|
Bean的定义 | @Component 衍生类@Repository(持久层) @Service(业务层) @Controller(控制层) | |
Bean的名称 | 通过id或name指定 | @Component(“person”) |
Bean的注入 | 或者通过p命名空间 | @Autowired(按名称注入) @Qualifier(按类型注入) |
生命过程,Bean的作用范围 | init-method 、destory-method;范围scope属性 | @PostConstruct初始化 @PreDestory销毁 @Scope设置作用范围 |
适用场景 | Bean来自第三方 | Bean的实现类由用户自己开发 |
3、对注解配置进行改造
基于注解的springIOC配置中,bean对象的特点和基于xml配置是一模一样的。
Note:如果我们使用纯注解配置,我们依旧要使用bean.xml配置文件
bean.xml配置文件中依旧包含以下信息
<context:component-scan base-package="com.simon"></context:component-scan>
<bean id="queryRunner" 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.cj.jdbc.Driver"></property>
<property name="jdbcUrl" value="jdbc:mysql://localhost:3306/spring?characterEncoding=utf8&serverTimezone=UTC"></property>
<property name="user" value="root"></property>
<property name="password" value="root"></property>
</bean>
3.1使用配置类代替配置文件
- @Configuration
作用:用于指定当前类是一个spring配置类,当创建容器时会从该类上加载注解,获取容器时需要使用AnnotationApplicationContext(有@Configuration注解的类.class)
属性:value:用于指定配置类的字节码
- @ComponenScan
作用:用于指定要扫描的包。作用和在spring的xml配置文件中的:<context:component-scan base-package=“com.simon” />是一样的
属性:basePackage:用于指定要扫描的包,和该注解中的value属性作用是一样的
- @Bean
作用:该注解只能写在方法上,表名此方法创建一个对象,并且存放入Spring容器中
属性:name:给当前@Bean注解方法创建的对象指定一个名称(即bean的id)
@Configuration
@ComponentScan("com.simon")
public class SpringConfiguration {
@Bean(name = "queryRunner")
public QueryRunner createQueryRunner(DataSource dataSource) {
return new QueryRunner(dataSource);
}
@Bean(name = "dataSource")
public DataSource createDataSource() {
ComboPooledDataSource cbd = new ComboPooledDataSource();
try {
cbd.setDriverClass("com.mysql.cj.jdbc.Driver");
cbd.setJdbcUrl("jdbc:mysql://localhost:3306/spring?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone = GMT");
cbd.setUser("root");
cbd.setPassword("root");
return cbd;
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}
3.2工程中的多个配置类
@Import
作用:用于导入其它配置类,在引入其它配置类时,其它配置类中的@Configuration写不写均可。
属性:value[]:用于指定其它的配置类字节码
-
父配置类
@Configuration @ComponentScan("com.simon") @Import(JdbcConfiguration.class) public class SpringConfiguration { }
-
子配置类
@Configuration public class JdbcConfiguration { @Bean(name = "queryRunner") public QueryRunner createQueryRunner(DataSource dataSource) { return new QueryRunner(dataSource); } @Bean(name = "dataSource") public DataSource createDataSource() { ComboPooledDataSource cbd = new ComboPooledDataSource(); try { cbd.setDriverClass("com.mysql.cj.jdbc.Driver"); cbd.setJdbcUrl("jdbc:mysql://localhost:3306/spring?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone = GMT"); cbd.setUser("root"); cbd.setPassword("root"); return cbd; } catch (Exception e) { throw new RuntimeException(e); } } }
3.3注解@ProPertySource
用于加载.properties文件中的配置。如当我们配置数据源时,可以把连接数据库的信息写入到properties文件中
属性:value[]:用于指定properties文件位置,如果类路径下,需要加上classpath
@PropertySource("classpath:jdbcConfig.properties")//在父类上添加该注解即可
-
jdbcConfig.properties配置文件
jdbc.driver=com.mysql.cj.jdbc.Driver jdbc.url=jdbc:mysql://localhost:3306/spring?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone = GMT jdbc.username=root jdbc.password=root
-
jdbcConfiguration类
@Configuration public class JdbcConfiguration { @Value("${jdbc.driver}") private String driver; @Value("${jdbc.url}") private String url; @Value("${jdbc.username}") private String username; @Value("${jdbc.password}") private String password; @Bean(name = "queryRunner") public QueryRunner createQueryRunner(DataSource dataSource) { return new QueryRunner(dataSource); } @Bean(name = "dataSource") public DataSource createDataSource() { ComboPooledDataSource cbd = new ComboPooledDataSource(); try { cbd.setDriverClass(driver); cbd.setJdbcUrl(url); cbd.setUser(username); cbd.setPassword(password); return cbd; } catch (Exception e) { throw new RuntimeException(e); } } }
4、Spring整合Junit
- 测试面临的问题,为什么要重新改造Junit
- 应用程序的入口(main方法)
- junit单元测试中,没有main方法也能执行,因为junit集成了一个main方法,该方法就会判断当前测试类中哪些方法有@Test注解,junit就让有Test注解方法执行
- junit不会管我们是否采用Spring框架,因为在执行测试方法时,junit根本不知道我们是否使用了Spring框架,所以就不会为我们读取配置文件/配置类创建Spring核心容器
- 整合的步骤
导入spring整合的junit的jar(坐标),即spring-test
使用Junit提供的一个注解把原有的main方法进行替换,替换成Spring提供的@Runwith
告知spring的运行器、spring和ioc创建是基于xml还是注解的,并说明位置
@ContextConfiguration
locations:指定xml文件的位置,加上classpath关键字,表示在类路径下
@ContextConfiguration("classpath:bean.xml")
classes:指定注解类所在位置
@ContextConfiguration(classes = SpringConfiguration.class)
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = SpringConfiguration.class)
public class AccountServiceTest {
@Autowired
private AccountService accountService;
@Test
public void testFindAll() {
List<Account> list = accountService.findAllAccount();
for (Account account : list) {
System.out.println(account);
}
}
Simeon郎
发布了77 篇原创文章 · 获赞 42 · 访问量 6万+
私信
关注
标签:xml,cbd,Spring,配置,Bean,bean,注解,IOC 来源: https://blog.csdn.net/dreame_life/article/details/104495984