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)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Spring框架是一个开源的Java应用程序框架,它提供了一个轻量级的、非侵入式的编程和配置模型,用于构建企业级应用程序。下面是Spring框架的一些核心原理: 1. 控制反转(IoC):控制反转是Spring的核心原则之一。它通过将对象的创建和依赖关系的管理交给Spring容器来实现。在传统的开发模式中,对象之间的依赖通常由对象自己创建和管理,而在Spring中,容器负责创建对象并将依赖注入到对象中。 2. 依赖注入(DI):依赖注入是控制反转的一种实现方式。Spring使用依赖注入来实现对象之间的解耦。通过注入依赖,对象不再负责自己的依赖关系,而是将这个责任交给Spring容器。这样可以提高代码的可测试性、可维护性和可扩展性。 3. AOP(面向切面编程):AOP是Spring框架的另一个重要特性。它可以在不修改源代码的情况下,通过在运行时动态地将额外的行为织入到程序中。AOP常用于处理横切关注点(如日志记录、事务管理等),从而提高代码的模块化和可重用性。 4. 声明式事务管理:Spring框架提供了声明式事务管理的支持,使得开发者可以通过配置方式来管理事务,而不需要显式地编写事务管理的代码。这样可以简化事务管理的过程,并提高代码的可读性和可维护性。 5. MVC(Model-View-Controller)架构:Spring框架提供了一个灵活的MVC架构,用于构建Web应用程序。它将应用程序划分为模型(Model)、视图(View)和控制器(Controller)三个部分,通过中央调度器(DispatcherServlet)来处理请求和响应。 6. 模块化设计:Spring框架采用了模块化的设计,它将各个功能划分为不同的模块(如核心容器、数据访问、AOP等),使得开发者可以根据需求选择需要的模块,并灵活地集成到自己的应用程序中。 这些是Spring框架的一些核心原理,它们共同构成了Spring框架的基础和特性。通过理解这些原理,可以更好地使用和扩展Spring框架,提高开发效率和应用程序的质量。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值