spring框架学习

spring框架学习

  • Spring是一个开源的、轻量级的容器(包含并管理对象的生命周期)框架

  • Spring是为了解决企业级开发中业务逻辑层中对象之间的耦合问题

  • Spring的核心是IOC和AOP

1. spring Bean

  1. Spring Bean是一个由Spring IOC容器实例化、组装和管理的对象。
  2. Java Bean是一个Java类:所有属性为private、提供默认构造方法、提供getter和setter、实现serializable接口。
  3. 对象就是普通的Java类实例化的产物,区别于上述Java bean的四点要求。

1.1 Spring bean的生命周期

在这里插入图片描述

BeanDefinition

Spring容器在进行实例化时,会将xml配置的的信息封装成一个BeanDefinition对象,Spring根据BeanDefinition来创建Bean对象,里面有很多的属性用来描述Bean。

1.2 spring框架中的单例bean不是线程安全的

Spring框架中有一个@Scope注解,默认的值就是singleton,单例的。因为一般在spring的bean的中都是注入无状态的对象,没有线程安

全问题,如果在bean中定义了可修改的成员变量,是要考虑线程安全问题的,可以使用多例或者加锁来解决

@Service
@Scope("singleton")
public class UserServiceImpl implements UserService{}
  • singleton:bean在每个Spring IOC中只有一个实例(单例)

  • prototype:一个bean的定义可以有多个实例

在这里插入图片描述

1.3 Sping中的循环依赖

循环依赖其实就是循环引用,在创建A对象的同时需要使用B对象,在创建B对象的也同时需要使用A对象,也就是两个或者两个以上的bean相互持有对方,最终形成闭环。

解决方法

使用Spring的三级缓存

缓存名称源码名称作用
一级缓存singletonObjects单例池,缓存已经经历了完整的生命周期,已经初始化完成的bean对象
二级缓存earlySingletonObjects缓存早期的bean对象(生命周期还没有走完)
三级缓存singletonFactories缓存的是ObjectFactory,表示对象工厂,用来创建某个对象的(可以解决创建代理对象的问题)

注意:三个级别缓存需一起使用才能解决大部分循环依赖问题,若只有一级和二级不能解决代理对象循环依赖问题,若没有二级依赖则可能对导致多次调用工厂,可能会生成多例对象

在这里插入图片描述

若构造方法出现了循环依赖问题

由于bean的生命周期中构造函数是第一个执行的,spring框架的三级缓存并不能解决,因此我们需要在构造器中加入注解**@Lazy**,什么时候需要对象再进行bean对象的创建

public A(@Lazy B b){
	System.out.println("A的构造方法执行");
	this.b = b;
}

2. AOP(面向切面编程)

AOP用于将那些与业务无关,但却对多个对象产生影响的公共行为和逻辑,抽取封装为一个可重用的模块,这个模块被命名为“ 切面 ”,减少系统中重复的代码,降低模块间的耦合度,同时提高系统的可维护性。

常见的AOP使用场景:核心是使用AOP的环绕通知+切点表达式(找到要记录日志的方法),通过环绕通知的参数获取请求方法的参数(类,方法,注解,请求方式等),获取到这些参数后,保存到数据库。

  • 记录操作日志
  • 处理缓存
  • Spring中内置的事务处理(声明式事务管理:本质上是通过AOP功能,对方法进行拦截,在执行方法之前开启事务,执行完后根据执行情况提交或者回滚事务)

例:(通过AOP进行操作自动填充操作数据时间)

  • 自定义一个注解
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface MyCut {
    String value();
}
  • AOP进行管理的目标方法
// 新增菜品
@MyCut("save")//使用自定义的注解进行标识
@Insert("INSERT INTO dish(name, price, create_time) VALUES(#{name}, #{price}, #{createTime})")
@Options(useGeneratedKeys = true, keyProperty = "id")
int insert(Dish dish);

//自定义的切面类,在该类中实现操作方法

@Component
@Aspect  //切面类
public class Aspect2 {
    //设置切点,使用了自定义注解的方法进行AOP管理
    @Pointcut("execution(* com.sky.mapper.*.*(..)) && @annotation(com.sky.aspect.MyCut)")
    public void myPointCut() {
    }
    @Before("myPointCut()")
    public void MyDoBefore(JoinPoint joinPoint) throws InvocationTargetException, IllegalAccessException, NoSuchMethodException {
        //判断是新增还是修改
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        MyCut annotation = signature.getMethod().getAnnotation(MyCut.class);
        String value = annotation.value();//获取到操作类型
        Object[] args = joinPoint.getArgs();//获取入参参数列表
        if (args.length > 0) {
            Object arg = args[0];//获取第一个参数(dish)
            LocalDateTime now = LocalDateTime.now();//获取当前时间
            if ("save".equals(value)) {
                //通过反射来调用
                Method setCreateTime = arg.getClass().getDeclaredMethod("setCreateTime", LocalDateTime.class);
                Method setUpdateTime = arg.getClass().getDeclaredMethod("setUpdateTime", LocalDateTime.class);
                setCreateTime.invoke(arg, now);
                setUpdateTime.invoke(arg, now);
            } else if ("update".equals(value)) {
                Method setUpdateTime = arg.getClass().getDeclaredMethod("setUpdateTime", LocalDateTime.class);
                setUpdateTime.invoke(arg, now);
            }
        }
    }
}

3. Spring中事务失效

导致事务失效原因:

  • 异常捕获处理

    在这里插入图片描述

  • 抛出检查异常

    在这里插入图片描述

  • 非public方法

    在这里插入图片描述

4. SpringMVC的执行流程

  1. 视图阶段(老旧JSP等)

    1. 用户发送出请求到前端控制器DispatcherServlet
    2. DispatcherServlet收到请求调用HandlerMapping(处理器映射器)
    3. HandlerMapping找到具体的处理器,生成处理器对象及处理器拦截器(如果有),再一起返回给DispatcherServlet。
    4. DispatcherServlet调用HandlerAdapter(处理器适配器)
    5. HandlerAdapter经过适配调用具体的处理器(Handler/Controller)
    6. Controller执行完成返回ModelAndView对象
    7. HandlerAdapter将Controller执行结果ModelAndView返回给DispatcherServlet
    8. DispatcherServlet将ModelAndView传给ViewReslover(视图解析器)
    9. ViewReslover解析后返回具体View(视图)
    10. DispatcherServlet根据View进行渲染视图(即将模型数据填充至视图中)
    11. DispatcherServlet响应用户

    在这里插入图片描述

  2. 前后端分离阶段(接口开发,异步)

    1. 用户发送出请求到前端控制器DispatcherServlet
    2. DispatcherServlet收到请求调用HandlerMapping(处理器映射器)
    3. HandlerMapping找到具体的处理器,生成处理器对象及处理器拦截器(如果有),再一起返
    4. 回给DispatcherServlet。
    5. DispatcherServlet调用HandlerAdapter(处理器适配器)
    6. HandlerAdapter经过适配调用具体的处理器(Handler/Controller)
    7. 方法上添加了@ResponseBody
    8. 通过HttpMessageConverter来返回结果转换为JSON并响应

在这里插入图片描述

5. Spring boot自动配置原理

  1. 在Spring Boot项目中的引导类上有一个注解**@SpringBootApplication**,这个注解是对三个注解进行了封装,分别是:

    • @SpringBootConfiguration:该注解与@Configuration注解作用相同,用来声明当前是一个配置类
    • @EnableAutoConfiguration:SpringBoot实现自动化配置的核心注解
    • @ComponentScan:组件扫描,默认扫描当前引导类所在包及其子包
  2. 其中**@EnableAutoConfiguration是实现自动化配置的核心注解。该注解通过@lmport注解导入对应的配置选择器。内部就是读取了该项目和该项目引用的Jar包的的classpath路径下META-INF/spring.factories**文件中的所配置的类的全类名。在这些配置类中所定义的Bean会根据条件注解所指定的条件来决定是否需要将其导入到Spring容器中。

  3. 条件判断会有像**@ConditionalOnClass**这样的注解,判断是否有对应的class文件,如果有则加载该类,把这个配置类的所有的Bean

    放入spring容器中使用。

@SpringBootApplication
public class JixiOrderSystemApplication {
    public static void main(String[] args) {
        SpringApplication.run(JixiOrderSystemApplication.class, args);
    }
}
@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan(
    excludeFilters = {@Filter(
    type = FilterType.CUSTOM,
    classes = {TypeExcludeFilter.class}
), @Filter(
    type = FilterType.CUSTOM,
    classes = {AutoConfigurationExcludeFilter.class}
)}
)

6.Spring 框架中常用注解

6.1 spring 常见注解
注解说明
@Component、@Controller、@Service、@Repository使用在类上用于实例化Bean
@Autowired使用在字段上用于根据类型依赖注入
@Qualifier结合@Autowired一起使用用于根据名称进行依赖注入
@Resource@Autowired + @Qualifier
@Scope标准Bean的作用范围
@Configuration指定当前是一个spring配置类,当创建容器时会从该类上加载注解
@ComponentScan用于指定spring初始化容器时要扫描的包
@Bean使用在方法上,标注将该方法的返回值存储到spring容器中
@Import使用@Import导入的类会被spring加载到IOC容器中
@Aspect、@Before、@After、@Around、@Pointcut用于切面编程(aop)
6.2 SpringMVC常见的注解
注解说明
@RequesMapping用于映射请求路径,可以定义在类上和方法上。用于类上,则表示类中的所有方法都是以该地址作为父路径
@RequestBody注解实现接收http请求的json数据,将json转换为java对象
@RequestParam指定请求参数的名称
@PathViriable从请求路径中获取请求参数(/user/{id}),传递给方法的形式参数
@RequestBody注解实现将controller方法返回对象转换为json对象响应给客户端
@RequestHeader获取指定的请求头数据
@RestController@Controller+@RequeseBody
6.3 SpringBoot常见注解
注解说明
@SpringBootApplicationspringBoot核心注解;组合注解,包含 @Configuration@EnableAutoConfiguration@ComponentScan;用于标识 Spring Boot 应用的主类;
@SpringBootConfiguration组合了-@Configuration注解,实现配置文件的功能
@EnableAutoConfiguration打开自动配置的功能,也可以关闭某个自动配置的选项
@ComponentScanSpring组件扫描

主播还在学习ing
| @SpringBootConfiguration | 组合了-@Configuration注解,实现配置文件的功能 |
| @EnableAutoConfiguration | 打开自动配置的功能,也可以关闭某个自动配置的选项 |
| @ComponentScan | Spring组件扫描 |

主播还在学习ing

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值