Spring框架的目标是通过启用基于POJO的编程模型,使Java EE开发更易于使用并促进良好的编程实践。
bean生命周期
1、需要初始化bean时,factory调用createBean进行实例化。
2、获取BeanDefinition对象中的信息进行实例化。并且这一步仅仅是简单的实例化,并未进行依赖注入。
3、实例化对象被包装在BeanWrapper对象中,接着Spring根据BeanDefinition中的信息进行依赖注入。
4、 注入Aware接口紧接着,Spring会检测该对象是否实现了xxxAware接口,并将相关的xxxAware实例注入给bean。
5、BeanPostProcessor当经过上述几个步骤后,bean对象已经被正确构造,但如果你想要对象被使用前再进行一些自定义的处理,就可以通过BeanPostProcessor接口实现。
6、InitializingBean与init-method
7、DisposableBean和destroy-method和init-method一样,通过给destroy-method指定函数,就可以在bean销毁前执行指定的逻辑。
keyword: factory createbean beandefinition wrapper aware postprocessor initializing destory
注解
1、@Controller:使用它标记的类就是一个Spring MVC Controller对象,即:一个控制器类。Spring使用扫描机制查找应用程序中所有基于注解的控制器类,分发处理器会扫描使用了该注解的方法,并检测该方法是否使用了@RequestMapping注解。Controller接口的实现类只能处理一个单一的请求动作,而@Controller注解注解的控制器可以同时支持处理多个请求动作,使程序开发变的更加灵活。
2、@RequestMapping:使用@RequestMapping注解的方法才是真正处理请求的处理器
3、@autowire:可以修饰在构造器、普通方法、成员变量、构造器or非静态方法入参上修饰【@Resource能用在:类、成员变量和方法上】。默认按byType自动装配【@Resource默认byName自动装配】。@Autowired只包含一个参数:required,表示是否开启自动准入,默认是true。
4、@Qualifier:意思是合格者,一般跟Autowired配合使用,需要指定一个bean的名称,通过bean名称就能找到需要装配的bean。
5、@Primary:当我们使用自动配置的方式装配Bean时,如果这个Bean有多个候选者,假如其中一个候选者具有@Primary注解修饰,该候选者会被选中,作为自动配置的值。
6、在类上面忘了加@Controller、@Service、@Component、@Repository等注解,spring就无法完成自动装配的功能
7、springmvc的启动是在DisptachServlet里面做的,而它是在listener和filter之后执行。如果我们想在listener和filter里面@Autowired某个bean,肯定是不行的,因为filter初始化的时候,此时bean还没有初始化,无法自动装配。如果工作当中真的需要这样做,我们该如何解决这个问题呢?
1 | public class UserFilter implements Filter { |
答案是使用WebApplicationContextUtils.getWebApplicationContext获取当前的ApplicationContext,再通过它获取到bean实例。
8、@Autowired功能虽说非常强大,但是也有些不足之处。比如:比如它跟spring强耦合了,如果换成了JFinal等其他框架,功能就会失效。@Resource是JSR-250提供的,它是Java标准,绝大部分框架都支持。
Spring加载流程以及三级缓存
AOP的实现原理
1、就是将那些与业务无关,却被业务模块所共同调用的逻辑封装起来,便于减少系统的重复代码,降低模块间的耦合度,并有利于未来的可操作性和可维护性。AOP的核心思想就是“将应用程序中的商业逻辑同对其提供支持的通用服务进行分离。”
2、两种方式生成代理对象:JDKProxy和Cglib具体使用哪种方式生成由AopProxyFactory根据AdvisedSupport对象的配置来决定。默认的策略是如果目标类是接口,则使用JDK动态代理技术,否则使用Cglib来生成代理。
事务
1、管理事务
2、配置事务
mvc
01、用户发送出请求到前端控制器DispatcherServlet。
02、DispatcherServlet收到请求调用HandlerMapping(处理器映射器)。
03、HandlerMapping找到具体的处理器(可查找xml配置或注解配置),生成处理器对象及处理器拦截器(如果有),再一起返回给DispatcherServlet。
04、DispatcherServlet调用HandlerAdapter(处理器适配器)。
05、HandlerAdapter经过适配调用具体的处理器(Handler/Controller)。
06、Controller执行完成返回ModelAndView对象。
07、HandlerAdapter将Controller执行结果ModelAndView返回给DispatcherServlet。
08、DispatcherServlet将ModelAndView传给ViewReslover(视图解析器)。
09、ViewReslover解析后返回具体View(视图)。
10、DispatcherServlet根据View进行渲染视图(即将模型数据填充至视图中)。
11、DispatcherServlet响应用户。
1、controller方法中为什么不能定义局部变量? 因为controller是默认单例模式,高并发下全局变量会出现线程安全问题 解决:1scope="prototype"每次都创建新的controller 2jdk提供了java.lang.ThreadLocal 3将全局变量都编程局部变量,通过方法参数来传递
2、SpringMVC中的拦截器和Servlet中的filter有什么区别? 都能过滤请求。Interceptor在实现上基于Java的反射机制,属于面向切面编程(AOP)的一种运用。一个拦截器实例在一个controller生命周期之内可以多次调用,按照配置的先后顺序进行拦截。但是缺点是只能对controller请求进行拦截,对其他的一些比如直接访问静态资源的请求则没办法进行拦截处理。Filter依赖于servlet容器。在实现上基于函数回调,可以对几乎所有请求进行过滤[主要是针对URL地址做一个编码的事情、过滤掉没用的参数、安全校验(比较泛的,比如登录不登录之类)],但是缺点是一个过滤器实例只能在容器初始化时调用一次。
3、Spring非单例注入的原理
本文链接: https://satyrswang.github.io/2021/10/06/spring/
版权声明: 本作品采用 知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议 进行许可。转载请注明出处!