构造函数的循环依赖,三级缓存可以解决吗?
嗯~ 构造函数的循环依赖,三级缓存是解决不了的。
这是因为,由于bean的生命周期中,构造函数是第一个执行的,如果在执行构造函数的时候,发现依赖了另外一个bean,并且是循环依赖,spring框架是解决不了的,此时就需要我们手动解决,当然解决方案,也很简单,通过一个注解就搞定了, 就是 @Lazy 注解,通过这个注解实现延迟加载,什么时候需要对象,再进行bean对象的创建。
PS:下面代码,只为帮助理解和演示:
什么是AOP ?
aop是面向切面编程,在spring中用于将那些与业务无关,但却对多个对象产生影响的公共行为和逻辑,抽取公共模块复用,降低耦合,一般像系统的公共日志记录,事务处理,权限的控制等都可以通过AOP来实现。
可能继续追问的问题:
1). 你们项目中有没有使用到AOP?
这个很多地方都用到了,比如我们当时在后台管理系统中,就是使用aop来记录了系统的操作日志、以及权限控制。那就来说一下,记录日志的操作思路吧。
主要思路是这样的,使用aop中的环绕通知 加上 基于注解@annotation 的切点表达式来实现的。
首先,自定义了一个注解,比如叫 @Log,然后哪些操作需要记录日志,我们就在哪些方法上加上这个注解。
然后再定义一个切面类,通过环绕通知,来获取原始方法在运行的各项信息,比如:类信息、方法信息、注解、请求方式、请求参数、当前操作人、操作时间、返回值等信息,全部记录下来,保存在数据库中。
当时,我们主要记录的是一些核心业务模块的增删改的操作日志,主要便于数据追踪。
2). AOP的底层是如何实现的?
SpringAOP的底层主要是通过动态代理技术实现的,主要是两种代理技术。一种是JDK的动态代理,而JDK的动态代理呢,有限制,只能针对于实现了接口的类做代理,所以,在spring中还有一种是Cglib动态代理,那Cglib动态代理呢,就没有这个限制。
3). JDK动态代理 与 Cglib动态代理有什么区别呢?
限制不同。 JDK动态代理,要求被代理对象必须实现了接口才可以。 而Cglib动态代理,无论是否实现接口都可以(只要类不是final修饰即可)。
代理对象不同。 JDK动态代理生成的代理对象,与被代理对象其实是实现了相同的接口,可以说是兄弟关系。 而Cglib动态代理生成的代理对象,其实是继承了被代理类,是基于继承体系的,所以是父子关系。 也正是因为此,所以Cglib不能为被final修饰的类做代理。
Spring中的事务是如何实现的?
spring实现的事务本质就是aop完成,对方法前后进行拦截,在执行方法之前开启事务,在执行完目标方法之后根据执行情况提交或者回滚事务。 而如果我们进行项目开发,不存在分布式事务问题,我们就可以直接使用Spring提供的@Transactional注解来控制事务即可。
可能继续发问的问题:
1). 在开发中,有没有遇到事务失效的场景 ?
在刚开始上班做项目时,遇到过,但是现在在做项目,写代码时,都会规避这些坑。 事务失效比较典型的场景呢就是:
第一个,如果业务方法上try、catch处理,自己处理了异常,没有抛出,就会导致事务失效,所以一般处理了异常以后,别忘了抛出去就行。
第二个,如果方法抛出检查异常,如果报错也会导致事务失效,因为默认spring事务管理只会针对于RuntimeException进行回滚。那这个呢,就可以在spring事务的注解上,就是@Transactional上配置rollbackFor属性为Exception.class,这样别管是什么异常,都会回滚事务。
第三个,是我早期开发中遇到的一个,如果业务方法上不是public修饰的,也会导致事务失效。
嗯,就能想起来那么多
2). 什么是事务的传播行为 ?
Spring的事务传播行为,指的是两个被事务控制的方法,相互调用的过程中,到底是加入到已存在的事务,还是创建一个新的事务,控制的是这个事儿。 我们设置事务的传播行为,可以通过 @Transactional 注解的propagation属性来设置,可取值有很多啊,但是常见的就只有两个:
REQUIRED:也是默认值,表示如果没有事务,就新建一个事务,如果有事务,就加入到已存在的事务中。
REQIRES_NEW:表示需要一个新的事务,无论当前环境是否存在事务,都会开启一个新的事务。
PS: 下面伪代码,仅为了帮助理解:
Plain Text
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
@Service
public OrderServiceImpl implements OrderService {
@Autowired
private OrderMapper orderMapper;
@Autowired
private OrderLogService orderLogService;
@Transactional
public void submitOrder(Order order){
try {
//.... 订单数据处理
//....
orderMapper.insert(order); //保存订单数据
} finally {
//.... 构造订单日志数据OrderLog
orderLogService.insertLog(orderLog); //记录订单日志, 无论是否下单成功, 都需要记录
}
}
}
Plain Text
复制代码
1
2
3
4
5
6
7
8
9
10
@Service
public OrderLogServiceImpl implements OrderLogService{
@Autowired
private OrderLogMapper orderLogMapper;
@Transactional(propagation=Propagation.REQUIRES_NEW)
public void insertLog(OrderLogorderLog){
orderLogMapper.insert(orderLog)
}
}
聊聊Spring框架中的常用注解 ?
额,这个就很多很多了。 我就分为这么几类,说一下吧。
第一类是:声明bean,有@Component、@Service、@Repository、@Controller
第二类是:依赖注入相关的,有@Autowired、@Qualifier、@Resourse
第三类是:设置作用域 @Scope
第四类是:spring配置相关的,比如@Configuration,@ComponentScan 和 @Bean
第五类是:跟aop相关做增强的注解 @Aspect,@Before,@After,@Around,@AfterReturning,@AfterThrowing,@Pointcut