Spring
Spring核心
- Spring IoC(控制反转):控制反转是一种设计思想,原本开发者需要手动创建的对象全部交予Spring进行管理。比如工作的时候,一个Service类可能依赖很多对象才能完成工作,如果我们需要手动去创建依赖对象,就需要搞清楚这些依赖对象的构造函数,但是用Ioc的话,我们只需要通过配置信息又或者注解的方式,把当前依赖对象交予Ioc去管理,在开发的时候我们只需要把他引入就可以了。
- AOP(面向切面编程):将一些与业务无关却为业务模块共同调用的封装起来,减少系统的复杂度,降低代码的耦合度,有利于代码未来的拓展和维护 比如:事务处理、日志管理、权限控制
Spring重要模块
- Spring Core:最基础的,Spring其他功能大多都依赖Spring Core
- Spring AOP:提供面向切面的变成实现
- Spring JDBC:JAVA数据库连接
- Spring JMS:JAVA消息服务
- Spring ORM:面向对象与数据库的映射
- Spring Web:为创建Web应用程序提供支持
- Spring Test:提供JUnit和TestNG测试的支持
@Controller/@RestController
单数使用@Controller返回的是一个视图,@RestController返回的是一个对象(JSON、XML),@RestController = @Controller + @ResponseBody
Spring Bean
Spring Bean的作用域
- singleton:只有唯一一个Bean实例,Spring默认使用的就是单例
- prototype:多例,每次请求都会创建一个新的Bean
- request:每一次http请求都会创建一个新的Bean实例 (该作用域适用于web)
- session:每一次http 的session会话里面创建一个新的Bean实例(该作用域适用于web)
- global-sesion:全局session,在spring 5 已删除(该作用域适用于web)
注意点
如果单例里面注入了多例,那么多例也会随之变成单例,因为Bean对象只有在初始化的时候才会注入依赖对象
解决方法: 继承ApplicationContextAware接口,手动获取bean
/**
* @Author: 木杉
* @e-mail: 819236727@qq.com
* @Date: 2021/3/11
* @Destrice:
*/
@Controller
@RequestMapping(value = "/hyb")
public class TestApi implements ApplicationContextAware{
private ApplicationContext applicationContext;
@GetMapping(value = "/test")
private void get() {
applicationContext.getBean(RequestBean.class).get();
}
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
this.applicationContext = applicationContext;
}
}
Spirng单例Bean的安全问题
多线程同时操作对象变量的时候,会存在安全隐患
解决方案:
- 避免在对象里面定义可变的成员变量
- 使用ThreadLocal
@Component/@Bean
- @Component作用在类上面,而@Bean作用在方法上面
- @Component通常是使用路径扫描的方式来装配到Spring容器中,@Bean用在方法上面,告诉Spring这是一个对象的实例
/**
* @Author: 木杉
* @e-mail: 819236727@qq.com
* @Date: 2021/3/11
* @Destrice:
*/
public class Test{
}
/**
* @Author: 木杉
* @e-mail: 819236727@qq.com
* @Date: 2021/3/11
* @Destrice:
*/
@Configuration
public class Test{
@Bean
public A a(){
return new A();
}
}
自动注入/构造注入/方法注入
自动注入
/**
* @Author: 木杉
* @e-mail: 819236727@qq.com
* @Date: 2021/3/11
* @Destrice:
*/
@Service
public class Test {
@Autowired
private A a;
}
构造注入
/**
* @Author: 木杉
* @e-mail: 819236727@qq.com
* @Date: 2021/3/11
* @Destrice:
*/
@Service
public class Test {
private A a;
public Test(A a){
this.a = a;
}
}
方法注入
/**
* @Author: 木杉
* @e-mail: 819236727@qq.com
* @Date: 2021/3/11
* @Destrice:
*/
@Service
public class Test {
private A a;
@Autowired
public void setA(A a){
this.a = a;
}
}
@Autowired/@Resource
@Autowired
- Spirng框架自带的装配注解
- autowired是通过类型(type)自动装配
- autowired如果找不到装配Bean会抛异常,如果允许控制可以通过@Autowired(required=false)
- 如果要通过name装配可以配合@Qualifier(value = “name”)
@Resource
- J2EE的装配注解
- 可以通过类型(type)和名称(name)装配,默认通过名称
当注解写在字段上时,默认取字段名进行安装名称查找,如果注解写在setter方法上默认取属性名进行装配。当找不到与名称匹配的bean时才按照类型进行装配。但是需要注意的是,如果name属性一旦指定,就只会按照名称进行装配
@Transactional
事务隔离级别
ISOLATION_DEFAULT:这是默认值,表示使用底层数据库的默认隔离级别。
ISOLATION_READ_UNCOMMITTED:该隔离级别表示一个事务可以读取另一个事务修改但还没有提交的数据。
ISOLATION_READ_COMMITTED:该隔离级别表示一个事务只能读取另一个事务已经提交的数据。
ISOLATION_REPEATABLE_READ:该隔离级别表示一个事务在整个过程中可以多次重复执行某个查询,并且每次返回的记录都相同。
ISOLATION_SERIALIZABLE:所有的事务依次逐个执行,这样事务之间就完全不可能产生干扰。
事务传播
PROPAGATION_REQUIRED:如果当前存在事务,则加入该事务;如果当前没有事务,则创建一个新的事务。(默认)
PROPAGATION_REQUIRES_NEW:创建一个新的事务,如果当前存在事务,则把当前事务挂起。
PROPAGATION_SUPPORTS:如果当前存在事务,则加入该事务;如果当前没有事务,则以非事务的方式继续运行。
PROPAGATION_NOT_SUPPORTED:以非事务方式运行,如果当前存在事务,则把当前事务挂起。
PROPAGATION_NEVER:以非事务方式运行,如果当前存在事务,则抛出异常。
PROPAGATION_MANDATORY:如果当前存在事务,则加入该事务;如果当前没有事务,则抛出异常。
PROPAGATION_NESTED:如果当前存在事务,则创建一个事务作为当前事务的嵌套事务来运行;如果当前没有事务,则该取值等价于TransactionDefinition.PROPAGATION_REQUIRED。
事务的回滚如果没有用@Transactional(rollbackFor = Exception.class),事务只会对不受检查异常(RuntimeException)进行回滚