Spring底层原理

2 篇文章 0 订阅

1.Spring

前置

第一个类
@Component
public class OrderService {
}
第二个类
@Component
public class UserService {

    @Autowired
    private OrderService orderService;

    public void test(){
        System.out.println(orderService);
    }
}
配置文件
@ComponentScan("com.zhouyu")
public class AppConfig {
}
执行文件
public class Test {

    public static void main(String[] args) {
        // 入口
        AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(AppConfig.class);
      UserService userService = (UserService)applicationContext.getBean("userService");
      userService.test();
    }
}
1.依赖注入
正常的 UserService user = new UserService(),其中的orderService是没有没有值的,但是bean对象会调用以下方法,并赋值
				for(Field field : userService.getClass().getDeclaredFields()){
            // 存在Autowired注解
            if (field.isAnnotationPresent(Autowired.class)){
                field.set(userService, "");
            }
        }
流程
UserService --> 调用无参的构造方法 --> 对象 --> 依赖注入 --> bean对象
2.Map单例池
什么是一处创建多处使用?
UserService userService = (UserService)applicationContext.getBean("userService");
UserService userService1 = (UserService)applicationContext.getBean("userService");
UserService userService2 = (UserService)applicationContext.getBean("userService");
打印他们的结果,默认是单例的所以是同一个对象
流程
UserService --> 调用无参的构造方法 --> 对象 --> 依赖注入 --> 放入map的单例池 --> bean对象
单例池,对象类名首字母小写作为key,对象做value的map对象
3.初始化前postConstruct
// 如何在初始化bean的时候,给系统管理员bean赋值
private User admain;

 @PostConstruct
 private void setupAdmain(){
   // mysql -->管理员信息 --> 初始化 admain --> admain
 }
流程
UserService-->无参构造-->对象-->依赖注入(@Autowired)
-->初始化前(@PostConstruct)-->初始化-->初始化后
-->放入map单例池-->bean  
4.初始化InitializingBean
@Component
public class UserService  implements InitializingBean {
    @Override
    public void afterPropertiesSet() throws Exception {
        // 初始化操作可以在这里做,比如前面的设置系统管理员
    }
}
// Spring操作,如果对象实现了InitializingBean接口,就执行afterPropertiesSet方法
if(orderService instanceof InitializingBean) {
    orderService.afterProertiesSet();        
}
流程
UserService-->无参构造-->对象-->依赖注入(@Autowired)
-->初始化前(@PostConstruct)
-->初始化(InitializingBean)
5.Bean的初始化、Bean的实例化
实例化就是到创建对象,初始化就是后面设置值得部分
6.初始化后(aop)
UserService-->构造器-->普通对象-->依赖注入(Autowire)--> 初始化前(PostConstruct)
--> 初始化(InitialLizingBean)-->初始化后(aop) --> 代理对象 --> 放入map代理池
7.细讲构造器
// spring使用构造器规则
1.有无参构造器也有有参构造器,默认使用无参构造器
public UserService() {
}
public UserService(OrderService orderService) {
  this.orderService = orderService;
}
2.只有一个有参构造器,就使用有参构造器
public UserService(OrderService orderService) {
  this.orderService = orderService;
}
3.只有两个有参构造器,spring不知道使用哪个,会报错nosuchmethodexception,com.test.<init>(),<init>()表示无参的构造方法
public UserService(OrderService orderService) {
   this.orderService = orderService;
}
public UserService(OrderService orderService,OrderService orderService1) {
    this.orderService = orderService;
}
可以再构造器上面加上@Autowire选择一个
8.构造器之by Type,by Name
@Bean
public UserService(OrderService orderService) {
   this.orderService = orderService;
}
@Bean
public UserService(OrderService orderService1) {
   this.orderService = orderService;
}
@Bean
public UserService(OrderService orderService1) {
   this.orderService = orderService;
}
现在单例池中就有了3个orderService实例,那么Spring怎么选择一个呢?
---先根据类型,再根据名称
aop原理
UserService类 ->推断构造器 ->普通对象
->依赖注入(@Autowire)
->初始化前(@PostConstruct)
->初始化(实现InitializingBean afterPropertiesSet)
->初始化后(aop)
->代理对象
->bean

实现aop步骤
1.开起aspect代理
@ComponentScan("com.zhouyu")
@EnableAspectJAutoProxy
public class AppConfig {
}
2.执行代理
@Aspect
@Component
public class ZhouyuAspect {

    @Before("execution(public void  com.zhouyu.service.UserService.test())")
    public void zhouyuBefore(JoinPoint joinPoint) {
        System.out.println("zhouyuBefore");
    }
}
3.拿到代理对象
 public static void main(String[] args) throws IllegalAccessException {
        // 入口
       AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(AppConfig.class);
      UserService userService = (UserService)applicationContext.getBean("userService");
      userService.test();
}
其实这时候只要从map单例池中取到的UserService对象,就是代理对象
4.原理
Class UserServiceProxy extents UserSevice{
	UserService target = 普通对象;
	public void test(){
	//before方法
	target.test();
	}
}
1.Spring会生成一个代理对象,继承于UserService,声明target等于普通对象
2.实际用户getBean拿到的是代理对象
3.代理对象执行test方法的步骤是切片方法中先执行before,然后普通对象执行test方法

Spring事务底层原理
为什么事务会失效

1.使用事务,先加上@Configuration
    @Transactional
    public void test(){
        System.out.println(orderService);
        a(); //a方法的事务失效了,因为这里普通对象执行a方法
    }

    @Transactional(propagation = Propagation.NEVER)
    public void a(){
        System.out.println(orderService);
    }
原理
Class UserServiceProxy extents UserSevice{
	UserService target = 普通对象;
	public void test(){
	//遍历@Transactional注解,事务管理器新建一个数据库连接
	connection.autoCommit = false;
	target.test();普通对象执行test
	connection.commit 或 connection.rollback
	}
}
2.若想让a方法用到事务,解决方法有两个
①新建一个newBean,autowire导入后,用newBean.a(),这里newBean就是一个代理对象
②直接autowire一个当前对象UserService,调用方法变为userService.a(),这里要注意循环依赖问题
Spring使用3级缓存来解决循环依赖
AService
1.AService -> 创建普通对象放入singletonFactories<aService,lambda>里面包含普通对象和beandefinition)
2.autoWire BService ->执行创建BService
BService
3.BService -> 创建普通对象
4.autoWire AService -> 去单例池SingletonObjects中找AService(没有找到)->在CreatSet中找到了,说明AService正在创建(证明循环依赖)
-> earlySingletonObjects(没有找到)
-> 通过singletonFactories判断是否要aop得到AService代理对象或者普通对象
-> 放入earlySingletonObjects
5.BService创建完成

AService继续
6.AService bean创建完成,将AService放入单例池

第一层 singletonObjects 单例池
第二层 earlySingletonObjects 存放临时的代理对象或者普通对象,这时对象都还没有创建完全
第三层 singletonFactories 存放lambda表达式(对象名称,普通对象,beandefinition)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值