02、Spring_IOC注解
一. 基于注解的IOC和DI
1、使用步骤
1、创建项目、导入依赖
2、创建dao层的接口和实现类
3、创建service层的接口和实现类
4、使用注解配置Bean,并且注入依赖
①使用@Component托管类,不写<bean />
②使用@Autowired注入对象,不写<property />
5、在xml里面打开注解的扫描开关
2、启动注解功能
<!--
打开注解的是扫描开关
1、这个开关,会扫描指定包下的所有类,识别类上的注解,然后进一步解析类中的属性设置,完成IOC 和 DI 的功能。
2、base-package: 需要指定一个包或多个包【多个包使用,逗号、分号、空格来隔开】
-->
<context:component-scan base-package="com.cwl"/>
3、声明bean的注解
IOC的注解解释:
1、@Component:
作用:用来告诉spring要创建这个类的对象,表示这个类是项目的一部分,是一个组件。
属性:
value: 用来配置对象的id值,如果不写,默认使用类名首写字母小写作为id值。
2、spring针对三层架构给出来的注解,这三个注解都是从@Component注解衍生出来的。
@Repository : 针对dao层
@Service : 针对service层
@Controller : 针对web层
例:
@Component
public class ClassName{}
4、配置bean的注解
@Scope : 相当于bean标签的scope属性
作用 : 用来控制单例和多例
singletion : 单例
prototype : 多例
@PostConstruct : 相当于bean标签的init-method属性
作用 : 用来初始化对象
@PreDestory : 相当于bean标签的destory-method属性
作用 : 用来销毁对象的
例:
@Scope
public class ClassName{}
@PostConstruct
public void init(){
System.out.println("init......");
}
5、依赖注入的注解
1、@Autowired : 相当于property标签的ref注入对象<property name=" ref=""/>
2、@Qualifier : 结合@Autowired使用,用于根据名称(标识符)注入依赖
3、@Resource : 相当于@Autowired + @Qualifier
4、@Value : 相当于property 标签的value, 注入普通的属性<property name="" value="" />
DI注入解释
@Autowired:
1. 按照属性的类型来匹配对象,如果找到的对象只有一个就注入。
2. 如果找到的对象有多个满足这种类型关系,会继续使用属性名当成是id名去匹配对象。
2.1 如果匹配上了,就注入对象
2.2 如果匹配不上,就报错
@Qualifier:
没有注入的功能,他仅仅是用来搭配@Autowired来使用,用来告诉@Autowired,按照什么id去找对象注入。
例:
@Autowired
@Qualifier("userDao")
private UserDao userDao;
DI 注入解释
@Resource:
1. 按照id值来找对象注入,能找到就注入,找不到就报错
2. 等价于 @Autowired + @Qualified 注入
例如:
@Resource(name="userDao")
private UserDao userDao;
DI注入解释
@Value : 普通数据注入
例:
@Value("${jdbc.username}")
private String username;
二. 纯注解开发IOC和DI
Spring 提供纯注解,并不是为了完全替代XML,而是提供另一种配置方案
1、@Configuration : 被此注入标记的类,是配置类等同于applicationContext.xml
2、@ComponentScan : 用在匹配类上,开启注解扫描,使用basePackage属性指定扫描的包
3、@PropertySource : 用在配置类上,加载properties文件。使用value属性指定properties文件路径
4、@Import : 用在配置类上,引入子配置类,用value属性指定子配置类的Class
5、@Bean : 用在配置类的方法上,把返回值声明为一个bean。用name/value属性指定bean的id
配置类:
1. @Configuration:
表示这是一个配置类,是从@Component变化过来的,所以这个配置类的对象也会被创建出来,放在IOC容器中。
2. @ComponentScan :
用来配置扫描包的。
例 :
@Configuration
@ComponentScan("com.cwl")
public class SpringConfigClassName{}
3. @PropertySource:
用来导入外部的properties文件。
@PropertySource(value="classpath:db.properties")
public class ClassName{
@Value("${db.driver}")
private String driver;
}
4. @Import :
用来导入其他类,被spring管理起来。
引入子配置类,并且支持数组注入
例如:
@Import({AppConfig.class , Student.class})
5. @Bean :
这个注解使用在方法上的,spring会自动调用这个方法,并且取得这个方法的返回值对象管理起来。
1. 默认使用方法名字作为这个管理的对象的id值。
2. 也可以通过他的value属性来设置id值。
3. @Bean注解标注的方法内部需要用到spring管理的一个对象,怎么解决?
4. 解决:
可以让spring注入进来
1. 在方法参数上声明即可,spring来调用这个方法的时候会自动的鞋带对象来调用!
2. 可以使用@Qualifier来指定注入的对象。
3. 也可以在形参上做手脚。
例:
@Bean
public DruidDataSource dataSource(){
// 1. 创建对象
DruidDataSource ds = new DruidDataSource();
// 2. 使用set方法来配置属性
ds.setDriverClassName(driver);
......
return ds;
}
@Bean注解 应用场景:
在需要spring创建某个类的对象,但是这个类又不能在他身上使用注解。
如:
只有一些第三方jar包里面的类,才要这样做。
三. 整合MyBatis【XML】
1、导入依赖
<!--整合mybatis用的jar包-->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<version>2.0.7</version>
</dependency>
<!--spring对jdbc的封装-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>5.1.2.RELEASE</version>
</dependency>
2、配置applicationContext.xml
<!--1.扫描包:: 专注于IOC和DI的注解-->
<context:component-scan base-package="com.cwl" />
<!--1.1 导入外部的properties文件-->
<context:property-placeholder location="db.properties" />
<!--1.2 让spring创建连接池的对象-->
<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
<property name="driverClassName" value="${db.driver}" />
<property name="url" value="${db.url}" />
<property name="username" value="${db.username}" />
<property name="password" value="${db.password}" />
</bean>
<!--
2. 整合MyBatis:: 使用两个类: SqlSessionFactoryBean 和 MapperScannerConfigurer
SqlSessionFactoryBean : 负责构建SqlSession对象。
MapperScannerConfigurer : 用来扫描dao接口。
-->
<bean class="org.mybatis.spring.SqlSessionFactoryBean">
<!--2.1 设置起别名的包名-->
<porperty name="typeAliasesPackage" value="com.cwl.bean" />
<!--2.2 设置连接的数据库是哪个-->
<property name="dataSource" ref="dataSource" />
</bean>
<!--3. 这里扫描包: 目的是为了让mybatis能够识别dao接口方法对应的映射语句,并且创建出来dao接口的代理对象-->
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basePackage" value="com.cwl.dao">
</bean>
四. 整合MyBatis【纯注解版本】
1、导入依赖
2、将配置applicationContext.xml转化为纯注解方式
@MapperScan("com.cwl.dao")
@PropertySource("classpath:db.properties") //带入外部的properties
@ComponentScan("com.cwl") //扫描包
@Configuration // 表示这是一个配置类,等价于applicationContext.xml
public class AppConfig{
@Value("${db.driver}")
private String driver;
@Value("${db.url}")
private String url;
@Value("${db.username}")
private String username;
@Value("${db.password}")
private String password;
@Bean
public DruidDataSource dataSource(){
//1. 创建druidDataSource对象
DruidDataSource ds = new DruidDataSource();
//2. 使用set方法来配置属性
ds.setDriverClassName(driver);
ds.setUrl(url);
ds.setUsername(username);
ds.setPassword(password);
return ds;
}
@Bean
public SqlSessionFactoryBean factoryBean(DruidDataSource dataSource){
//1. 创建sqlSessionFactoryBean对象
SqlSessionFactoryBean sf = new SqlSessionFactoryBean();
//2. 使用set方法来配置属性
sf.setTypeAliasesPackage("com.cwl.bean");
sf.setDataSource(dataSource);
return sf;
}
/**
1. 如果在类当中使用了MapperScannerConfigurer ,那么将会导致AppConfig类被初始化的时机提前,是的属性都无法完成注入。
2. 解决办法:
2.1 把这个方法标记成static静态方法。
2.2 把这个方法放到隔壁的配置类中,然后在这个类里面使用@Import来导入他。
2.3 不写这个方法,这需要在配置类上打上注解 @MapperScan("com.cwl.dao")
@Bean
public MapperScannerConfigurer mas(){
//1. 创建MapperScannerConfigurer 对象
MapperScannerConfigurer msc = new MapperScannerConfigurer();
//2. 使用set方法来配置属性
msc.setBasePackage("com.cwl.dao");
return msc;
}
*/
}
五. 整合Junit
1、导依赖
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>5.1.2.RELEASE</version>
</denpendency>
2、打注解
@RunWith(SpringJUnit4ClassRunner.class) //用来指定测试的运行环境
@ContextConfiguration(classes=AppConfig.class) // 负责创建工厂
//@ContextConfiguration("classpath:applicationContext.xml") //负责创建工厂
public class TestUserServiceIm{
@Autowired
private UserService us;
@Test
public void testAdd(){
us.add();
}
}
扩展`
1. @AllArgsConstructor : 用来创建满参的构造函数
2. @NoArgsConstructor : 用来创建无参的构造函数
3. @Setter : 用来生成set方法
4. @Getter : 用来生成get方法
5. @ToString : 用来生成toString方法
6. @Data : 创建get、set和toString 方法 一般使用此注解。
7. @Builder : 会生成构建者对象,使用它可以更加灵活的构建的javaBean对象