Spring中的注解
一: IOC中注解
1.1 使用注解的形式声明对象
@Repository(持久层)
@Service(业务层)
@Contorller(表现层)
@Component(没有层)
/*
被此注解声明的类:
它表示将当前的类创建一个对象,然后放入一个IOC容器中
相当于xml中的一个bean标签
<bean id ="" class= "">
也可以使用@Repository(id)来指定创建出的bean对象的id
如果不指定,默认是当前类名首字母小写
*/
@Repository
public class UserDaoImpl implements UserDao {
}/
* 常用的声明创建对象的注解
* 标注在类上
1. @Component
用于实例化对象,相当于配置文件中的< bean id="" class=""/>
它支持一个属性value,相当于xml中bean的id。如果不写,默认值为类名的首字母小写
2. @Controller @Service @Repository
这三个注解的功能跟@Component完全一样,只不过他们三个比较有语义化。
2.1 @Controller
一般标注在表现层的类上
2.2 @Service
一般标注在业务层的类上
2.3 @Repository
一般标注在持久层的类上
推荐使用这三个,当一个类实在不好归属在这三个层上时,再使用@Component
1.2 对象的生存范围
@Scope
(单多例对象)
* 标注在类上
1. 单例
@Scope("singleton")
声明一个单例对象
2. 多例
@Scope("prototype")
声明一个多例对象
# @Scope 用于声明bean的作用范围(单例和多例)
相当于配置文件的<bean scope="">
1.3 对象声明周期的两个特殊的方法
@PostConstruct
@PreDestroy
* 标注在方法上
1. 对象创建之后
@PostConstruct
被此注解标注的方法表示在对象的创建之后自动执行
2. 对象销毁之前
@PreDestroy
被此注解标注的方法表示在对象的销毁之前自动执行
* @PostConstruct @PreDestroy
这两个注解标注方法分别在对象的创建之后和销毁之前执行。
相当于 < bean init-method="init" destroy-method="destory" />
1.4 对象的依赖注入
@Autowired
给类中的属性赋值
* 这个注解表示依赖注入
@Autowired(byType byName)
他可以标注在类上,也可以标注在方法上
标注在属性上
* 标注在属性上
@Autowired
private UserDao userDao;
1.当Spring解析到这个标签的时候(寻找bean对象)
1.1 首先会去IOC容器中,按照这个注解标注的属性的类型[UserDao],去寻找有没有对应的bean对象
2. 找不到的情况:
直接报错
3. 找的到的情况下(匹配对应的bean对象):
3.1 找到一个:
找到一个的话,就会进行依赖注入,也就是给属性赋值
3.2 找到多个:
再接着按照注解标注的属性名称(userDao)进行匹配
如果匹配得到,就行依赖注入
如果匹配不到的话就报错
# 注意:
当使用@Autowired注解标注属性的时候,属性对应的set方法可以省略不写
解决注解的匹配错误的问题
可以在属性的类型上更换 Private UserDaoImpl userDao;
可以在属性名称上更换和该类在生成对象时存入map集合相同的名称
在使用生成对选哪个的注解的时候如果不指定id默认为该类的首字母小写
Private UserDao userDaoImpl;
标注在方法上
* 标注在方法上
@Autowired
public void setUserDao (UserDao userDao){
this.userDao=userDao;
}
* 当这个注解标注在方法上的时候:
代表这个方法默认会被spring调用执行
当这个方法需要参数的时候
就会在IOC容器中根据参数的类型去寻找
当寻找不到的时候就会报错
当寻找到一个的时候,就会进行依赖注入
当寻找到多个的时候,接着就会根据参数的名称就行寻找
当寻找到多个的的时候就会报错
当寻找到一个的时候就会进行依赖注入
@Qualifier
* 要跟@Autowired结合使用
代表在按照类型的基础上在按照这个注解指定的名称去寻找
@Autowired
@Qualifier("userDaoImpl")
pirvate UserDao userDao;
@Resource
* 此注解由java提供,在9以后就废弃了(byName,buType)
# 表示先按照名称查找 再按照类型查找
@Resouce
private UserDao userDao;
* Spring会在他的IOC容器中先按照名称进行寻找
如果找到了,就进行依赖注入
如果找不到的话,就按照类型进行查找
如果找到一个的话就进行依赖注入
如果找到多个的话,就报错
# 注意:
@Resource(name = "userDaoImpl1") 如果直接使用name指定名称,他就只会按照名称匹配
不会再按照类型进行寻找和匹配
总结
xml配置 | 注解配置 | 说明 |
---|---|---|
< bean id="" class="" > | @Component @Controller @Service @Repository | bean的实例化 |
< property name="" ref=""> | @Autowired、@Qualifier、 @Resource | bean的对象属性注入 |
< property name="" value=""> | @Value | bean的简单属性注入 |
< bean scope=""> | @Scope | 控制bean的作用范围 |
< bean init-method=“init” destroy method=“destory” /> | @PostConstruct @PreDestroy | bean创建之后和销毁之前分别调用的方法 |
# @Component @Controller @Service @Repository
告诉Spring,想让Spring生成对象
# @Autowired
告诉Spring,我想要什么,也就是让Spring给我们依赖注入
二: AOP中的注解
2.1 将增强类转换为切面
@Aspect
# 使用在类上
* 这个注解是在配置aop的时候使用的
表示将自定义的增强类转换为切面
切面: 切点+ 增强
2.2 四大通知
@Pointcut
# 声明在方法上
# 作用:
标注一个方法为切点方法
用法
//定义切点 方法名随便起
@Pointcut("execution(* com.itheima.dao.impl.*.*(..))")
public void gt() {
}
@Before
前置通知
# 声明在方法上
表示声明的增强方法在指定的切点之前执行
用法
//定义切点 方法名随便起
@Pointcut("execution(* com.itheima.dao.impl.*.*(..))")
public void gt() {
}
//声明前置通知
@Before("gt()")
public void before() {
System.out.println("方法执行之前");
}
@AfterReturning
后置通知
# 声明在方法上
# 表示声明的指定的方法在切点正常执行后执行
用法
@AfterReturning("gt()")
public void afterMethod() {
System.out.println("方法执行之后");
}
@AfterThrowing
异常通知
# 声明在方法上
# 表示所声明的指定的增强方法在切点发生异常的时候执行
用法
@AfterThrowing("gt()")
public void exception() {
System.out.println("发生异常执行的方法");
}
@After
最后通知
# 声明在方法上
# 表示所声明的指定的增强的方法在指定的切点的最后执行
用法
@After("gt()")
public void after() {
System.out.println("方法执行之后");
}
2.3 环绕通知
@Around
表示我们可以以编码的形式实现四大通知类型
@Around("gt()")
public void arroud(ProceedingJoinPoint pjp) {
try {
System.out.println("方法执行之前");
//切点的方法执行了
pjp.proceed();
System.out.println("方法正常执行后");
} catch (Throwable throwable) {
throwable.printStackTrace();
System.out.println("方法执行发生了异常");
} finally {
System.out.println("方法最终执行");
}
}
2.4 开启事务管理
声明事务的开启
@Transactional
# 可以标注在类上也可以标注在方法上
标注在类上表示此类中的所有的方法全部被事务管理
标注在方法上表示此方法才被事务管理
# 声明事务的开启
用法
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-6n2siD64-1595148658120)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\1571122434281.png)]
三: 配置文件中的注解
3.1 开启自动包扫描
@ComponentScan
包扫描
# 标注在配置类上
* 这个注解的作用的是在配置类上
作用是让 IOC类型的注解生效
只有开启了包扫描,IOC类型的注解才可以使用和生效
当使用纯注解版的时候在配置类上使用
相当于xml中的
<context:component-scan base-package="com.itheima"></context:component-scan>
* 用法:
@ComponentScan("com.itheima")
3.2 开启自动代理
@EnableAspectJAutoProxy
也就是让AOP的注解生效
# 声明在配置类上
* 作用:
让AOP类型的注解生效
@Aspect @Before @Arround 等
用法:
@ComponentScan("com.itheima")
@EnableAspectJAutoProxy
public class SpringConfig {
}
3.3 开启事务管理
@EnableTransactionManagement
# 声明在配置类上
* 表示 事务管理的注解类生效
@Transactional
只有开启了事务管理 对应的事务管理的注解才生效
相当于xml中的
<!--事务注解驱动-->
<tx:annotation-driven></tx:annotation-driven>
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-yZD3jaua-1595148658130)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\1571123989537.png)]
标注为配置类
@Configuration
# 标注在类上的
* 声明该类是一个配置类
也就是在Spring容器启动的时候会自动扫描所有的配置类
然后将配置类中的bean对象放入Spring容器中
* 用法:
@Configuration
public class Student{
}
引入配置文件
@PropertySource
# 声明在类上
* 用于外部的properties类型的文件
* 用法:
@PropertySouce("db.properties")
引入配置类
@Import
# 标注在类上
* 在一个配置类上导入其他类的内容
* 用法:
@Import(DataSource.class)
四: Spring整合单元测试(Junit)
# 需求:
在单元测试中不使用new 对象的形式获取service层的对象
而使用的是依赖注入的形式
把service层的对象当作属性放在单元测试中
# 单元测试的运行原理:
* 在单元测试中,当我们点击run的时候,底层工作的其实是一个运行期
默认情况下是ParentRunner
这个运行器是junit提供的,它是不认识 Spirng环境的
这也就意味着,他无法从Spring的容器中去获取bean对象
# 如果想从Spring容器中去获取对象,那就必须想认识Spring容器
这个时候Spring提供一个运行器,这个运行器就认识Spirng环境
也就是可以获取对象了
首先要做的是添加坐标
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-a4NjZhCn-1595148658153)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\1570873301924.png)]
@RunWith
切换junit的运行环境
# 这个注解是junit提供的注解
他可以切换junit的运行环境
* 用法:
@RunWith(SpringJUnbit4ClassRunner.class)
表示从junit的运行环境切换到Spring的运行环境
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-DEpd2AAa-1595148658164)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\1570873741723.png)]
@ContextConfiguration
读取配置文件的信息
# 一般声明在测试类上
# 这个注解表示读取一个配置类的信息
* 用法:
@ContextConfiguration(classes=SpirngConfig.class) 读取的是配置类
@ContextConfiguration("classpath:application.xml") 读取的是配置文件
他有一个属性是来接收要读取的配置类的信息的
结果
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-AL7z7Iii-1595148658171)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\1570874065462.png)]