1.IoC常用注解
常用的注解:
a. Bean声明
@Component(元件的意思) : 通用的Bean声明,属性value代表Bean的id,默认是类名首字母小写
@Controller:用于web层(表现层)
@Service:用于service层(业务层)
@Repository(仓库的意思):用于dao层(持久层)
b. 依赖注入
@AutoWired:常用,根据类型自动注入,用于注入Bean类型,当同一类型的Bean有多个时,会根据变量名自动寻找,如过找不到匹配的,就抛运行时异常
@AutoWired
@Qualifier:依赖于@AutoWired使用,注入value属性指定的id的对应的Bean,解决了一个类型多个Bean的问题,但不常用
@Resource:注入name属性指定的id对象的Bean
@Value:注入基本数据类型或String,可以写spEl(spring的El表达式)
c. 作用范围及生命周期
作用范围:
@Scope value属性默认singleton单例,可以指定prototype多例
生命周期:
@PostConstruct:相当于<bean>标签中的init-method属性,作用于Bean初始化之后要执行的方法上
@PreDestory:相当与<bean>标签中destory-method属性,作用在Bean销毁前要执行的方法上
2.IoC增删该查案例
要用到DBUtils/DataSource这些封装好的类,我们不可能去源码给相应的位置添加@Component或者@AutoWired注解,怎么办呢?
先用xml的方式实现:
<context:component-scan base-package:"cn.itcast">
<bean name="queryRunner" class="org.apche.commons.dbutils.QueryRunner">
<!--这里为啥要用ds,跟dbutils的源码有关-->
<constructor-arg name = "ds" ref="dataSource">
</bean>
<bean name="dataSource" class="com.mchange.v2.c3p0.ComboPoolDataSource">
<property name="driverClass" value="com.mysql.jdbc.Driver"></property>
<property name="jdbcUrl" value="jdbc:mysql://localhosy:3306/mybatis01"></property>
<property name="user" value="root"></property>
<property name="password" value="root"></property>
</bean>
3.IoC全注解开发
全注解开发就是用注解代替上面写的xml配置文件
第一步:定义一个父配置类用@Configuration声明,代替原来注解空间声明<context:component-scan base-package:“cn.itcast”>
创建容器时,用AnnotationConfigApplicationContext实现类,传递配置类,创建容器,这个步骤是容器创建的入口
我们想将不同层级的配置用不同的子配置类来定义(也声明@Configuration注解),那么需要在父配置类上声明@Import()引入自配置类的字节码对象,属性是value,值是Class[]
关于@Configuration,如果不写,要保证创建容器时,将哪个需要的配置类字节码对象传递进去,这样spring就识别这是配置类,或者@Import在父配置类引入,虽然如此,建议只要是配置类,都把@Configuration写上
第二步:定义创建DBUtils/DataSource类的方法,方法上声明@Bean注解,这个注解会将方法返回的Bean对象放入spring容器,属性name代表Bean对象的id,如果不写,默认是方法名,注意不是返回的类名。
第三步:解决DataSource对象创建时硬编码造成的耦合,抽取数据库连接参数(4个)为成员变量,添加一个jdbc.properties配置文件,里面配置的是键值对形式的数据库连接信息,在配置类上声明@PropertySource,属性value是配置文件的路径,classpath:jdbc.properties声明是类路径,加载jdbc.properties之后,在成员变量上声明@Value标签,属性value可以使用spring的EL表达式${jdbc.driver}…
有个小细节:创建对象的方法需要的参数(一般都是Bean对象)是默认@Qualifier注解,自动注入的,@Qualifier作用与方法参数时,不用依赖@AutoWired注解
代码:
@Configuration
@PropertySource("classpath:jdbcConfig.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;
/**
* 获取QueryRunner对象,并添加到spring容器
* @param dataSource
* @return
*/
@Bean(name = "queryRunner")
public QueryRunner createQueryRunner(@Qualifier("createDataSource") DataSource dataSource){
return new QueryRunner(dataSource);
}
/**
* 获取DataSource对象,并添加到spring容器
* @return
*/
@Bean
public DataSource createDataSource(){
ComboPooledDataSource dataSource = new ComboPooledDataSource();
try {
dataSource.setDriverClass(driver);
dataSource.setJdbcUrl(url);
dataSource.setUser(username);
dataSource.setPassword(password);
return dataSource;
} catch (PropertyVetoException e) {
e.printStackTrace();
}
return null;
}
}
4.spring整合junit
我们为了单元测试时只关注测试的逻辑代码,而不关注spring容器的创建,所以我们想将junit单元测试程序入口main改写,改写成可以加载spring容器的main方法,就提出了spring整合junit
maven依赖:spring-test junit
小细节,如果spring是5.x 那么要求juni版本t是4.12及以上,才可以实现整合
注解:在测试类上声明两个注解
a. 配置文件是配置类
@RunnerWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = SpringConfiguration.calss)
b. 配置文件是xml文件
@RunnerWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations= classpath:bean.xml)
如果有要求的情况下,我们按照要求来,如果我们来指定要求,建议springIoc使用注解+xml的方式,我们自定义的类可以用注解方式注入,其他封装好的类使用xml方式注入。
有两个我们用到的属性是name的标签:@Resource/@Bean
有两个地方我见到了classpath :@PropertyResource/@ContextConfiguration 都跟配置文件的加载有关。