spring问题点

1.事务

1.1.事务传播

同一个类中 事务A调非事务B B抛异常 AB事务生效(具有传播性)
同一个类中 事务A调非事务B A抛异常 AB事务生效
也就是主方法加了事务注解 则方法内调用的其他本类方法无需加事务注解,
发生异常时可以保证事务的回滚
最常用

1.2.代理

需要用到代理的是,非事务A调用事务B,如果想让B的事务生效,需要用代理模式

2.循环依赖

@Validated 底层为AOP机制,注解会导致循环依赖问题(即使加了spring:main:allow-circular-references: true)。

3.spring扩展点

3.1重写afterPropertiesSet()方法

AbstractAutowireCapableBeanFactory#initializeBean()方法中会执行我们重写的方法。
spring问题点_第1张图片
spring问题点_第2张图片

3.2.@PostConstruct

AbstractAutowireCapableBeanFactory#initializeBean()方法中会执行我们加了@PostConstruct注解的方法。
是CommonAnnotationBeanPostProcessor执行的,方法在他的父类InitDestroyAnnotationBeanPostProcessor
spring问题点_第3张图片
spring问题点_第4张图片
也就是在3.1方法的上面

3.3.initMethod

spring问题点_第5张图片

3.4.BeanPostProcessor接口

重写这两个方法

    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        return bean;
    }

    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        return bean;
    }

AbstractAutowireCapableBeanFactory#initializeBean()方法中会执行我们重写的方法。
分别在invokeInitMethods方法的前后执行
spring问题点_第6张图片
也可以实现bean创建后的逻辑,但是要注意类型判断,不然每个bean(包括系统级的bean)初始化时都会调用我们重写的方法。

4.bean的作用域

4.1.单例

singleton(默认)
所有线程共享,对于有状态的单例bean存在线程安全问题
有状态的单例bean(它是有存储能力的。也就是说至少有一个属性来标识它目前的状态,意思就是你想在代码里用一个变量存储一个值,在代码运行期间想要实时获取,且不同用户值不同,例如租户id)

public class TestManagerImpl implements TestManager{  
    private User user;    
  
    public void deleteUser(User e) throws Exception {  
        user = e ;           //1  
        prepareData(e);  
    }  
  
    public void prepareData(User e) throws Exception {  
        user = getUserByID(e.getId());            //2  
        .....  
        //使用user.getId();                       //3  
        .....  
        .....  
    }     
} 
//不同对象的行为不同

如果该Bean配置为singleton,会出现什么样的状况呢?
如果有2个用户访问,都调用到了该Bean.
假定为user1,user2
当user1 调用到程序中的1步骤的时候,该Bean的私有变量user被付值为user1
当user1的程序走到2步骤的时候,该Bean的私有变量user被重新付值为user1_create
理想的状况,当user1走到3步骤的时候,私有变量user应该为user1_create;
但如果在user1调用到3步骤之前,user2开始运行到了1步骤了,由于单态的资源共享,则私有变量user被修改为user2
这种情况下,user1的步骤3用到的user.getId()实际用到是user2的对象。(我的理解是配置成singleton会造成资源混乱问题-对于有状态的bean)
正确使用方式

    /**
     * 当前租户编号
     */
    private static final ThreadLocal<Long> TENANT_ID = new TransmittableThreadLocal<>();
    /**
     * 获得租户编号。
     *
     * @return 租户编号
     */
    public static Long getTenantId() {
        return TENANT_ID.get();
    }

    public static void setTenantId(Long tenantId) {
        TENANT_ID.set(tenantId);
    }

4.2多例

prototype
每次都是获取到新的对象,线程安全
定义方式
spring问题点_第7张图片

你可能感兴趣的:(Spring,spring,java,后端)