JavaWeb复习

JavaWeb
Spring
Spring AOP
含义
面向切面编程,说的通俗易懂就是可以动态的,不修改源代码的情况下为程序添加功能,如在一个方法的前后添加一下功能。具体实现:在beans.xml中定义一个切面(包含新功能的类)和一个切点(表示在哪个类的哪个方法添加切面)
AOP底层
底层实现是通过代理对象,代理对象类继承普通对象类,代理对象中有一个target属性(它就是依赖注入后的普通对象),在代理对象中,会重写切点方法(在重写的方法里面加入切面逻辑以及调用target对象的切点方法)
Spring事务底层原理
Spring事务底层也是基于AOP。如果类中加了@Transactional,在创建该类bean的 初始化后  这个过程,就会生成代理对象。通过代理对象执行某个方法时,先在代理对象中判断改方法是否有@Transactional,有就重写这个方法,1. 先通过事务管理器新建一个数据库连接,2. 然后关闭数据库自动提交,3. 再通过target执行普通对象的方法。4. 最后数据库提交或者回滚。
事务传播机制(事务嵌套)
默认是将内层事务合并到外层一起提交,有异常一起回滚。
其他事务传播:1. @Transactional(propagation=Propagation.NEVER):表示如果已经存在事务的话,会抛出异常。2. propagation=mandatory:外层没有事务,抛出异常。3. propagation=support:内层事务是否生效依赖外层,外层是事务才生效。
注意:事务方法只能通过代理对像调用,才会生效(如果在一个类中一个普通方法调用一个有事务注解的方法,是不会生效的,因为普通方法调用相当于是普通对象调用的事务方法,解决办法,增加一个属性,自己注入自己,然后在普通方法中调用事务方法)。
Spring IOC
Spring IOC
控制反转(依赖注入),一种面向对象编程的思想,通过引入IOC容器,利用依赖注入的方式,实现对象之间的解耦。(联想齿轮。bean对象创建通过反射实现)
IOC容器:管理bean对象,负责创建对象和建立对象间的依赖。
Bean之间的关系
1. 继承。2. 依赖(如果某个bean依赖其他bean,创建该bean时会先创建依赖的那个bean)。3. 引用(通过property对bean起别名)
创建bean
Spring如何创建bean对象
1. 通过构造方法创建一个普通对象。2. 对普通对象进行依赖注入。3. 进行初始化(包括初始化前,初始化,初始化后)。4. 将完整的bean对象放入map单例池中
初始化前过程(通过@PostConstruct注解,也称后置处理器)
作用于bean对象创建过程中的初始化前。原理就是:通过反射判断创建的对象中是否有带有这个注解的方法,有的话就执行(通过这种方式,程序员可以对对象里的属性赋值等操作)
初始化过程
如果创建的对象实现了InitializingBean这个接口,就会在该类中实现一个初始化方法(程序员可以做一些初始化工作),在bean初始化的时候就会判断该对象是否实现了这个接口,如果实现了就执行该初始化方法
初始化后过程
初始化后可以进行AOP,会产生代理对象,如果有代理对象,就把代理对象放单例池中。
推断构造方法是什么
在创建bean对象时,前面会先创建普通对象,如果类中有多个构造方法,spring会选择无参的构造方法,如果没有就会报错,也可以加@Autowired来告诉spring选择哪个构造方法。
依赖注入先bytype再byName是什么
创建bean时,如果类属性中有@Autowired(或者构造方法需要传某个对象),就会给它注入值,先去map单例池中找是否存在,先通过byType找,如果只有一个直接赋值,如果有多个再byName找(如果bytype找到多个,且byName没找到则报错)。如果map单例池中没有就直接创建一个bean再赋值。
普通对象和bean对象区别
Bean对象就是在普通对象的基础上进行依赖注入,放入map单例池过后的对象
配置bean
@Configuration
@Configuration用于定义配置类,被注解的类内部包含有一个或多个被@Bean注解的方法,这些方法将会被用于构建bean对象。@Configuration注解的类本身也是一个bean对象。
@Component
可以用于注册所有bean((@Controller和@Service和@Repository,分别用于组测controller,service,dao层))
为什么有了@Compent,还需要@Bean呢?
如果想将第三方的类变成组件,你又没有没有源代码,也就没办法使用@Component进行自动配置,这种时候使用@Bean就比较合适了。
注入bean
@Autowired与@Resource都可以用来装配bean. 都可以写在字段上,或写在setter方法上
 @Autowired:默认按类型装配(这个注解是属业spring的)有三种方法注入:1. 属性注入,2. 构造方法注入,3. set方法注入
@Resource:默认按照名称进行装配(这个注解属于J2EE的)
循环依赖
定义
创建bean a时,需要b,创建b时需要a
具体解决方案:三级缓存
一级缓存:就是单例池,存放完整的单例bean
二级缓存:1.用于存放还没有经过完整bean生命周期步骤的单例bean。2.保证不会重复创建多个不完整的bean
三级缓存:存放的lambda表达式(其中包含对应的普通对象和是否需要aop的一些信息)
创建过程
1. 开始创建A,先把A名称放入creatingSet中,表示A正在创建。2. 创建A普通对象后,将lambda表达式存到三级缓存中(lambda表达式包含A的普通对及相关信息,如是否需要AOP)3. 对A中属性B进行填充时,先到单例池找是否有B,这时没有,就开始创建B。4. 创建B普通对象后开始填充A,现在单例池中找,没找到。5. 然后判断是否在creatingSet中,找到则出现了循环依赖。6. 然后到二级缓存中找是否存在A,此时没找到。7. 然后通过三级缓存获取A的lambda,根据是否需要AOP,创建A代理对象或者普通对象。8. 最后将创建的A对象放入二级缓存。9. 继续后续操作完成B的创建。10. 继续完成A的后续创建。
导致循环依赖失效原因及解决
情况1:构造方法导致循环依赖失效
原因:a构造方法需要b,b构造方法需要a,这样连普通对象都生成不了
解决:在构造方法前加@lazy,通过这种方式不会产生循环依赖(原理是先直接给该类属性生成一个代理对象,并未真正生成对应的bean,而是在具体调用该属性的时候再去生成真正对应的单例bean,此时当前类已经生成了单例bean,所以不会出现循环依赖。)
情况2:@Async 会导致循环依赖失效
原因:因为如果类本身有aop的话,在循环依赖时会提前生成代理对象,而提前生成的代理对象只会处理aop, 在创建bean对象最后步骤里会判断二级缓存是否已经存在该代理对象,如果存在,就不会创建新的代理对象,但是@Async并没有处理,所以又会创建一个处理@Async的代理对象,这样就会存在两个不同的代理对象,所以会抛出异常。
解决方法:可以通过在会导致循环依赖的类属性前加@lazy,通过这种方式不会产生循环依赖(原理是先直接给该类属性生成一个代理对象,并未真正生成对应的bean,而是在具体调用该属性的时候再去生成真正对应的单例bean,此时当前类已经生成了单例bean,所以不会出现循环依赖。)
单例bean和单例模式区别
单例bean:可以一个类对应不同名称的多个bean
单例模式:一个类对应的bean只能有一个
Springboot
Springboot优点
1.简洁,配置方便(无代码生成、无需编写XML,全部都集成在框架中)
2.内嵌web服务器(不用把项目打包成war,发布到如tomcat服务器上)
3.自动配置Spring以及第三方功能(如开发web程序,只需要导入web包就能自动配置web对应的依赖,且自动协调它们之间版本关系)
4.更好的监控,检查(如运维人员可以很方便的监控项目的状态)
缺点:1. 迭代快。2.封装深(不容易懂底层)
SpringBoot常用注解
1. @Controller 处理 http 请求。
2. @RequestMapping 配置 url 映射。
3. @RestController直接输出到页面(等同于@Controller +@ResponseBody。而@Controller:页面跳转 )。
4. @PathVariable 获取 url 参数。
5. @RequestParam 获取请求参数(post 或 get 都可以)。
6. @Autowired自动装配
7.@Component 配置bean
访问网址响应流程
1. 先跟据网址访问到tomcat服务器。2. 然后找到项目对应的DispatcherServlet(它的属性中有Spring容器,里面包含了所有的bean)3. 然后DispatcherServlet找到对应的Controllerbean,遍历其中的方法找到对应的方法。4. 执行对应方法并返回。
项目启动
创建springApplication对象,然后执行该对象的run方法。run方法核心功能:创建spring容器和创建相关的bean对象。(这个就是spring中处理的事,springboot还需要做一些整合的工作,比如一些初始化和自动装配的操作)
具体
构造springApplication对象
判断应用类型(如servlet,reactive ,如何判断?:类加载器是否加载成功)
通过spring.factories  加载应用上下文初始器和应用事件监听器(实际就是一个类路径,可以通过这个创建对应的监听器。)
给它的一个属性赋值传入的启动类(因为后面run方法中会对启动类的注解进行解析)
调用springApplication的run方法
创建监听器(用于监听run方法的执行。)
根据应用类型创建上下文(上下文包含Spring容器)
执行上下文初始化器的初始化方法(主要就是识别启动类,方便后续对其注解进行解析,以及注册spring的核心组件类)
执行refresh方法(主要就是自动装配和启动spring容器)
SpringBoot自动配置原理
自动装配就是从自动配置类(如spring.factories)中获取到对应的bean对象,然后由spring容器来帮我们进行管理。
比如:引入reids的maven后,就会有对应jar包,然后里面有对应的自动配置类,里面就会根据条件装配生成bean对象放到spring容器中
条件装配底层原理?
条件装配:根据是否存在某些类或bean对象,或者根据配置文件中的一些属性来进行装配。如:@ConditionalOnClass({a.class}):通过类加载器去加载a这个类,能加载才执行)
原理:ASM 是一个 Java 字节码操控框架 1. 先通过ASM工具获取字节码文件中@ConditionalOnClass后的字符串“a.class”,2. 再判断这个类是否能加载,3. 最后决定是否装载。
扩展:Springboot启动时扫描哪些需要创建bean也是通过ASM来判断扫描路径下的类是否包含@component或者@bean。而不是把扫描路径下所有类字节码文件都加载到jvm中,通过反射来判断是否存在@component或者@bean(这样浪费内存空间)
bean后置处理器?
通过bean后置处理器可以修改bean里面的属性。(如springboot默认端口信息是在TomcatServletWebServerFactory这个bean中,如过配置文件中自定义了端口,就会通过bean后置处理器来进行修改)
拦截器
底层是AOP,使用:
1. 先创建拦截器(实现 HandlerInterceptor 接口,实现一些方法:如方法执行前或执行后执行一些逻辑),
2. 然后配置拦截器,指定拦截规则(实现WebMvcConfigurer,然后定义拦截规则 )
stater组件
目的是方便开发,引入相关stater组件后,可以导入对应功能的jar包和维护jar包版本间的依赖。 还有就是stater组件内部集成了自动装配的机制,对于它所需要的维护的外部化配置可以在配置文件中配置就可以了(如reids的接口等)
Springboot底层如何判断选择tomcat 还是jett?
Springboot 是先创建Spring容器,再启动tomcat或者jett,具体选择哪个是根据项目中有哪个相关的依赖。Spring默认为tomcat是因为pom.xml中spring-boot-starter-web中默认有tomcat的依赖。
跳转
重定向(客户端跳转,地址栏变化):return “redirect:+地址”;
内部转发(服务器跳转,地址栏不变,可携带参数和request范围值):return “forword:+地址”;
Mybatis
动态Sql
动态sql就是根据查询条件不同动态的拼接sql语句(如,if、when等等)
分页查找
逻辑分页(查出全部数据到内存,再取分页数据,比较占内存,一般不用,mybatis支持逻辑分页,通过传RowBounds参数实现)
物理分页(通过limit实现,常用)
mybatis方案
1. sql语句中分页。
2. 基于mybatis 中interceptor拦截器,在select语句执行前,动态去拼接分页关键字。如:pagehelper
3.mybatis中有一个RowBounds对象,可以实现逻辑分页(数据都会读到内存(不是一次性读),根据需求分页)
Mybatis缓存
一级缓存:MyBatis 默认启用一级缓存,同一个用户调用了相同的select 语句,则直接会从缓存中返回结果(缓存到sqlsession中,默认select使用缓存,insert,update,delete 是不使用缓存的)。(可以配置cache,来调整缓存大小,刷新周期,以及缓存策略等)
二级缓存: 开发者可以自己配置二级缓存,二级缓存是全局的,是对所有用户select使用缓存;
不同数据源
可以让不同的mapper文件对应不同的数据源,这样service在操作不同的mapper时即操作了不同的数据源
$和#区别
KaTeX parse error: Expected 'EOF', got '#' at position 30: …,常用动态设置表名和排序字段,#̲是一个占位符,可以防止sql注…先值替换 在编译
Mybatis关系映射
就是查询时表之间的关联查询,一对一关系实现(比如学生实体类中包含的地址也是一个实体类,查询的时候返回值address需要封装所以采用关联查询,在返回值resultMap中 ,通过association来封装address(它会在address.xml根据id再查询一次地址信息),一对多则是collection)
SpringMvc
配置
配置文件web.xml中配置DispatcherServlet及映射路径,以及初始化springmvc配置文件路径spring-mvc.xml。在spring-mvc.xml中配置视图解析器以及扫描包的路径。
项目启动
1.Tomcat启动。2.解析web.xml ,其中listener创建spring容器(父容器)servletContext。3.DispatcherServlet实例化,DispatcherServlet对象.init()创建spring容器(子容器)。4.接收请求。扩展:一个DispatcherServlet对应一个Spring子容器,子容器可以共用父容器中的bean。一般项目就一个DispatcherServlet
访问流程(接收请求及响应)
网址:localhost:8080/testWeb/app/test。1. 根据ip加端口访问到tomcat,再根据项目名找到对应的项目,然后根据app目录找到对应的DispatcherServlet(它的属性中有Spring容器,里面包含了所有的bean)2. 然后DispatcherServlet找到Controllerbean,遍历其中的方法找到是否有test方法。3. 执行test方法并返回值到至视图解析器(spring-mvc.xml),视图解析器返回对应的jsp到前台。
JSP
JSP(Java Server Pages)技术就是一种将java信息转化成html信息的技术, 它有九大内置对象:response,exception等(实现页面中的一些特定功能,比如数据传送、页面重定向、自动刷新、异常处理、操作Cookie等。9大对象包含了四大作用域的对象(pageContext当前页面有效,request一次请求有效,session一次会话中有效,application整个应用有效)。)
Servlet
生成动态Web内容。( 客户端请求->服务器转发至servlet-> Servlet 生成动态Web内容并将其传给服务器->服务器将响应返回给客户端。)
Shiro
是一种安全框架,用主要用于身份验证和授权。自定义realm:登陆的时候,将用户的的权限,角色赋值给用户。然后给url设置访问权限,满足权限才能访问。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值