spring基于注解的IOC配置
1. 注解分类:
初始的xml配置:
< bean id= "" class = "" scope= "" init- method= "" destroy- method= "" >
< property name= "" vaule= "" | ref= "" > < / property>
< / bean>
a. 用于创建对象
其作用与xml配置中编写一个< bean> 标签作用一样
b. 用于注入数据
其作用与xml配置中的< bean> 标签内编写一个< property> 标签作用一样
c. 用于改变作用范围
其作用与xml配置的< bean> 标签中使用scop属性实现的功能是一样的
d. 生命周期相关
其作用与xml配置的< bean> 标签中使用init- method/ destroy- method属性实现的功能是一样的
2. 使用spring基于注解的IOC配置:
a. 导入相关jar包
spring- aop- 5.0 .2 . RELEASE. jar -- 基于注解开发的必备jar包
spring- beans- 5.0 .2 . RELEASE. jar -- 中间4 个为核心容器的jar包
spring- context- 5.0 .2 . RELEASE. jar
spring- core- 5.0 .2 . RELEASE. jar
spring- expressoin- 5.0 .2 . RELEASE. jar
spring- jcl- 5.0 .2 . RELEASE. jar -- 集成了apache的日志组件做成了自己的jar包
b. 创建配置文件,添加约束,标识使用注解开发而非xml文档
/ resource/ anno_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">
< ! -- 告诉spring在创建容器时需要扫描的包,该包中包含了基于注解配置类-- >
< ! -- 使用context命名空间下的component- scan标签-- >
< context: componet- scan base- package = "cn.mysilent" > < / context: componet- scan>
< / beans>
3. 用于创建对象的注解:
a. @Component :
1. 用于将当前类对象加入到核心容器中
2. 属性:
value:用于指定该bean的id。不写时,默认id为首字母小写的类名
b. @Controller :
1. 与@Component 功能与属性一致
2. 一般用于表现层
c. @Service :
1. 与@Component 功能与属性一致
2. 一般用于业务层
d. @Repository :
1. 与@Component 功能与属性一致
2. 一般用于持久层
@Controller / @Service / @Repository 三个注解功能都和Component一致,只是为了更加清晰的指明该对象用于哪一层
对于不属于三层架构的对象使用Component注解就好
4. 用于注入参数的注解:
a. @Autowired :
1. 自动按照类型注入。
只要核心容器中有唯一一个bean对象类型与待注入的变量类型一致就能成功注入,否则报错
类型的比较过程直接跳过key,比较容器中value值的类型
2. 出现位置:变量定义上,方法上
3. 使用注解注入时,成员变量的set方法不再必须
4. 如果核心容器中有多个bean对象类型与待注入变量类型一致时
spring会将变量名作为key值在容器中进行查找,如果找到一致的,则注入该key对应的value值类型的对象
当没有匹配的key值在容器map中时,程序报错
b. @Qualifier :
1. 在按照类型注入的基础上再按照名称注入。优化了Autowired注解的功能
但是它在给类成员注入时不能单独使用
只在给方法参数注入时可以单独使用
2. 属性:
value:用于指定注入的bean类型的id
3. 当对变量使用时,必须在变量上加上@Autowired 注解,二者搭配使用
c. @Resource :
1. 直接按照bean的id注入,它可以单独使用
2. 属性:
name:用于指定注入的bean类型的id
d. @Value :
1. 专门用于注入基本属性和String类型。
@Autowired / @Qualifier / @Resource 不能注入基本数据类型和String类型
2. 属性:
value:用于指定数据的值。该值可以使用spring中的SpEL ( spring中的EL表达式)
形式:${ 表达式} -- EL表达式写在jsp中,则为jsp的EL表达式,从4 个域中获取数据
-- EL表达式写在spring的注解/ 配置文件中,则为SpEL,从spring指定位置获取数据
-- EL表达式写在mybatis的注解/ 配置文件中,则从mybatis指定位置获取数据
5. 用户改变作用范围的注解:
a. @Scop :
1. 用于指定bean的作用范围
2. 属性:
value:用于指定bean对象的作用范围。常用singleton ( 默认) / prototype
6. 与生命周期相关:
a. @PostConstruct
1. 标识在方法上,标识该方法为bean对象初始化方法
b. @PreDestroy :
1. 标识在方法上,标识该方法为bean对象的销毁方法
spring中新注解:用于消除仍然存在的xml配置文件
1. 以上介绍的注解只能标注在自定义的类上,而jar包中定义的类不能使用
使得在使用注解时,如QueryRunner等jar包中定义的类仍然需要配置在xml文档中
于是spring中允许自定义一个类,该类用作xml配置文件的功能
2. 新注解:
a. @Configuration :
1. 指定当前类是一个配置类
2. 当配置类作为AnnotationConfigApplicationContext创建ApplicationContext对象的参数时,可以省略( 不建议)
b. @ComponentScan :
1. 用于通过注解指定spring创建容器时需要扫描的包
2. 属性:
basePackage ( value) :指定创建容器时扫描的包
@ComponentScan ( basePackage= { "xxx" } ) 效果等同于:
< context: componet- scan base- package = "xxx" > < / context: componet- scan>
c. @Bean :
1. 用于将当前方法的返回值作为bean对象存入spring的IOC容器
2. 属性:
name:指定存入容器时的key。不写时使用默认值,为该方法的方法名
d. @Import :
1. 用于导入其他的注解类,将各个小的配置类import 到一个大的配置类中,此时参数仅传递大配置类. class 即可
不再需要传递多个配置类. class
2. 属性:
value:用于指定其他配置类的字节码文件。
e. @PropertySource / @PropertySources :
1. 用于指定properties配置文件的位置
2. 属性:
value:指定配置文件的名称和路径
使用关键字classpath,表示类路径下。如@PropertySource ( "classpath:jdbc.properties" )
3. 如果使用注解配置方法时,如果方法有参数,spring框架会去查找容器中是否有可用的bean对象
查找方式与@Autowired 注入方式一样
4. 原始注解配置的xml文档:消除了自定义类的bean标签配置
/ resource/ anno_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">
< ! -- 告诉spring在创建容器时需要扫描的包,该包中包含了基于注解配置类-- >
< ! -- 使用context命名空间下的component- scan标签-- >
< context: componet- scan base- package = "cn.mysilent" > < / context: componet- scan>
< ! -- 配置QueryRunner,为了使每个查询不相互干扰,配置该对象的创建为多例prototype-- >
< ! -- 如果QueryRunner是单例对象,则面临多个dao使用时,可能引发线程安全问题-- >
< 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/test" > < / property>
< property name= "user" value= "用户名" > < / property>
< property name= "password" value= "密码" > < / property>
< / beans>
5. 使用自定义注解类来代替anno_bean. xml文档:
/ config/ SpringConfiguration. java
@Configuration
@ComponentScan ( "cn.mysilent" )
public class SpringConfiguration {
@Bean ( name= "runner" )
@Scop ( "prototype" )
public QueryRunner createQueryRunner ( DataSource dataSource) {
return new QueryRunner ( dataSource) ;
}
@Bean ( name= "dataSource" )
public DataSource createDataSource ( ) {
try {
ComboPoolDataSource ds = new ComboPoolDataSource ( ) ;
ds. setDriverClass ( "com.mysql.jdbc.Driver" ) ;
ds. setJdbcUrl ( "jdbc:mysql://localhost:3306/test" ) ;
ds. setUser ( "root" ) ;
ds. setPassword ( "12345" ) ;
}
}
}
注意:
我们在xml配置文件中,为了保证线程安全问题,将QueryRunner对象的产生设置为多例对象
因此在,QueryRunner对象的创建上加上@Scop 注解
6. 使用properties配置文件动态更新配置类:
/ resource/ jdbc. properties
jdbc. driver= com. mysql. jdbc. Driver
jdbc. url= jdbc: mysql: / / localhost: 3306 / test
jdbc. username= root
jdbc. password= 1234
/ config/ JdbcConfiguration. java
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;
@Bean ( name= "runner" )
@Scope ( "prototype" )
public QueryRunner createQueryRunner ( @Qualifier ( "ds2" ) DataSource dataSource) {
return new QueryRunner ( dataSource) ;
}
@Bean ( name= "ds2" )
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) ;
}
}
@Bean ( name= "ds1" )
public DataSource createDataSource1 ( ) {
try {
ComboPooledDataSource ds = new ComboPooledDataSource ( ) ;
ds. setDriverClass ( driver) ;
ds. setJdbcUrl ( "jdbc:mysql://localhost:3306/test02" ) ;
ds. setUser ( username) ;
ds. setPassword ( password) ;
return ds;
} catch ( Exception e) {
throw new RuntimeException ( e) ;
}
}
}
@Configuration
@ComponentScan ( "com.itheima" )
@Import ( JdbcConfig. class )
@PropertySource ( "classpath:jdbcConfig.properties" )
public class SpringConfiguration {
}
7. 使用AnnotationConfigApplicationContext创建核心容器:
ApplicationContext coreObj = new AnnotationConfigApplicationContext ( Configuration注解类. class ) ;
8. 原则:结合使用
自定义的类建议使用注解
jar包中已有的类建议用xml配置
spring整合Junit单元测试
1. 使用步骤:
a. 导入相关jar包:
spring- test- 5.0 .2 . RELEASE. jar
b. 使用Junit提供的注解将原有的main方法替换为spring提供的能够生成容器的main方法
注解:@RunWith
属性:
指定替换的main方法所在类的字节码文件
@RunWith ( SpringJunit4ClassRunner. class )
public class AccountServiceTest {
}
c. 告知spring的运行器,spring的IOC创建是基于xml还是基于注解,并说明配置文件的位置
注解:@ContextConfiguration
属性:
locations:指定xml文件位置。关键字classpath表示在类路径下
classes:指定注解类所在的位置
@RunWith ( SpringJunit4ClassRunner. class )
@ContextConfiguration ( classes= SpringConfiguration. class )
public class AccountServiceTest {
@Autowired
private IAccountService as = null;
}
d. 当使用spring 5.0 + 版本时,要求Junit的版本为4.12 +