目录
10、BeanFactory和ApplicationContext
1、Spring核心模块
- 核心容器(Core Container)
提供依赖注入和Bean管理功能(Spring容器),主要组件是BeanFactory,它使用控制反转将应用程序配置和依赖规范与实际的应用代码分开。
- ApplicationContext(应用上下文模块)
该模块扩展了BeanFactory的概念,国际化(I18N)消息,应用程序生命周期事件,和验证提供支持。此模块还提供了许多的企业服务,例如JNDI访问,EJB集成,远程和调度。
- 面向切面编程(AOP)
- Web
提供与web应用相关的功能(Socket、Spring MVC、web上下文等)
- DAO
封装对数据库的访问,同时基于AOP模块提供了事务管理。
2、SpringMVC
一个web三层架构模型,通过把Model、View、Controller分离,将web层进行职责解耦,把复杂的web应用分成逻辑清晰的几部分,简化开发,方便组内开发人员的配合。
- View(JSP),视图层,用来与用户打交道。负责接收数据,以及显示数据给用户;
- Controller(Servlet),控制层,负责找到合适的模型对象来处理业务逻辑,转发到合适的视图;
- Model(JavaBean),模型层,与数据库交互,完成具体的业务工作,例如:开启事务、转账等。
2.1、控制层(@Controller)、业务逻辑层(@Service)、持久层(@Repository)
- @Controller注解标记的类表示该类是一个控制器,通过在该类方法上增加@RequestMapping注解,可以接收web请求,实现前后台的交互。
- @Service注解标记的类表示该类是项目具体业务实现类,用于处理具体的业务逻辑。
- @Repository注解用于标注数据访问组件(Dao组件),通常用于与数据库的交互。
2.2、@ResponseBody 和@Controller的区别
@RestController = @ResponseBody + @Controller
@Controller与html配合使用,用于返回一个视图。在只有@Controller注解的类方法中,方法返回一个字符串,视图解析器会把该字符串对应的视图返回给前端。
@RestController用于返回对象,将对象以json或xml的形式写入http相应中,属于Restful Web服务。
3、SpringMVC工作流程
- 浏览器发送的请求都会交给DispatcherServlet(接收请求,响应结果);
- DispatcherServlet会查找到HandleMapping(处理器映射器),映射到请求对应的Controller,进行具体的逻辑处理;
- Controller处理完成后,返回一个ModelAndView给DispatcherServlet;
- DispatcherServlet通过ViewResolver视图解析器找到对应的视图对象View(解析物理视图,返回逻辑视图);
- 视图对象View负责渲染,并返回到浏览器;
4、springmvc的控制器是单例的吗?是线程安全的吗?
默认是单例的,可以通过@Scope注解设置模式:singleton,prototype,request,session,global session。由于是单例,所以只要不在控制器中定义成员变量,就是线程安全的。
单例的好处在于不用每次调用控制器时都去实例化对象,可提高性能。
5、@Autowired和@resource的异同
同:两者都可标注在字段或者setter方法上,用以Bean的自动注入。
异:
- @Autowired是由Spring提供;@Resource JDK提供;
- @Autowired只按照byType 注入;@Resource默认按byName自动注入;
- @Autowired默认按type注入,如果想按name注入,需配合@Qualifier一起使用;@Resource默认按name注入,可通过name和type属性,查找Spring中符合条件的Bean,找不到抛异常。
6、Spring单例和单例模式的区别
单例模式是指在一个jvm进程中仅有一个实例,而Spring单例是指一个Spring Bean容器(ApplicationContext)中仅有一个实例。
但如果在Spring中定义了多个相同类型的Bean,那么每一个Bean都可实例化一个对象,在IOC容器中也就存在了一个类的多个实例。
7、BeanDefinition包含了哪些信息
用于保存 Bean 的相关信息,包括属性、构造方法参数、依赖的 Bean 名称及是否单例、延迟加载等,它是实例化 Bean 的原材料,Spring 就是根据 BeanDefinition 中的信息实例化 Bean。
8、spring的核心是什么?
IOC(控制反转)和AOP(面向切面)。
IOC:把要在程序中实例化的对象配置到文件中(配置文件/注解),通过应用上下文(ApplicationContext)将对象交由Spring容器管理,在使用该对象的时候,不需要手动去new对象,可直接从容器中获取bean。
好处:降低组件之间的耦合,提供单例模式支持(不用手动实现)。
AOP:在系统中提升业务的分离,把日志、安全、事务等东西(切面)和核心业务分离开,基本实现是对相关方法进行拦截,添加所需的处理动作。
好处:减少系统的重复代码,降低模块之间的耦合度。
方面、连接点、通知、切入点、引入、目标对象、AOP代理、织入。
9、FactoryBean
FactoryBean是一个工厂Bean,它是一个接口,主要的功能是动态生成某一个类型的Bean的实例,也就是说,我们可以自定义一个Bean并且加载到IOC容器里面。
它里面有一个重要的方法叫 getObject()
,这个方法里面就是用来实现动态构建Bean的过程。
getBean(“beanName”):返回getObject()返回的对象。
getBean(“&beanName”):返回FactoryBean对象本身。
BeanFactory负责生产和管理Bean的一个工厂接口,提供了IOC容器的底层和基础规范;
FactoryBean是一种Bean的创建方式,是对Bean的一种扩展。
10、BeanFactory和ApplicationContext
BeanFactory(Bean工厂)是访问IOC容器的核心接口,只提供了实例化对象和getBean的功能。使用懒加载的方式,在每次获取对象时Spring容器才会创建对象。
BeanFactory:应用启动时占用资源少。
ApplicationContext(应用上下文)继承BeanFactory接口,在BeanFactory的基础上扩展了很多高级特性(统一的资源文件访问方式、同时加载多个配置文件、支持国际化等)。在IOC启动时就创建所有的Bean。
资源比较充足的情况下,建议使用ApplicationContext。
实例:
1、BeanFactory:延迟加载,应用启动的时候占用资源少。
2、ApplicationContext:应用启动时加载所有Bean,启动慢,占用资源较多,但后续没有了创建对象的额外开销,系统运行速度变快。且能在应用启动时及时发现系统中的配置问题。
但是使用ClassPathXMLApplicationContext的方式可能会造成多次初始化应用上下文,所以可以使用ApplicationContext工具类的方式进行bean的获取。
创建一个类继承ApplicationContextAware,使用该子类前需初始化Spring容器。
11、Spring的自动装配
- no:默认的方式是不进行自动装配的,通过手工设置ref属性来进行装配bean。
- byName:通过bean的名称进行自动装配,如果一个bean的 property 与另一bean 的name 相同,就进行自动装配。
- byType:通过参数的数据类型进行自动装配。
- constructor:利用构造函数进行装配,并且构造函数的参数通过byType进行装配。
- autodetect:自动探测,如果有构造方法,通过 construct的方式自动装配,否则使用 byType的方式自动装配
注:@Autowired和@Resource之间的区别
@Autowired默认是按照类型装配注入的,默认情况下它要求依赖对象必须存在(可以设置它required属性为false)。
@Resource默认是按照名称来装配注入的,只有当找不到与名称匹配的bean才会按照类型来装配注入。
12、Spring Bean
12.1、Spring Bean的作用域
Singleton:默认值,创建容器时创建Bean,以单例方式存在。
Prototype:每次请求都会创建一个新的Bean实例。
Request:每个HTTP请求都会创建一个新的Bean。
Session:同一个session共享一个Bean。
-
12.2、Spring的单例Bean的线程安全问题
如果单例Bean不定义可变的成员变量,则线程是安全的。
如果单例Bean状态可变,且同时被多个线程调用,则可能存在线程安全问题。
解决方法:
Bean中尽量避免可变的成员变量;
在类中定义ThreadLocal成员变量,将线程需要的可变变量保存在ThreadLocal中。
12.3、Bean的生命周期
实例化、属性赋值、初始化、销毁。
1、容器寻找Bean的定义并利用反射进行实例化;
2、依赖注入(IOC),根据Bean的配制,进行Bean的属性注入;
3、处理Aware接口
Bean实现BeanNameAware接口:setBeanName(),传递Spring配置文件中Bean的ID;
Bean实现BeanFactoryAware接口:setBeanFactory(),传递Spring工厂;
Bean实现ApplicationContextAware接口:setApplicationContext(),传入Spring上下文;
4、Bean存在实现了BeanPostProcessors接口的实例A:实例A的postProcessBeforeInitialization();
5、Spring配置文件中配置init-method方法;
6、Bean存在实现了BeanPostProcessors接口的实例A:实例A的postProcessAfterInitialization();
完成Bean的创建-------Bean使用中-----------------------------------------------------------------------------------
7、Bean实现了DisposableBean接口:调用destroy()方法;
8、Spring配置文件中配置destory-method方法
注:BeanPostProcessors接口的两个方法,主要是在Bean实例化之后、初始化前后,允许对bean实例进行自定义的修改。
12.4、Spring创建Bean的三种方式
- 通过构造方法创建
目标类提供构造函数,由Spring自带的工厂(BeanFactory)维护和管理目标类。
- 通过静态工厂方法创建
目标类提供一个静态工厂方法,把类交给提供的静态工厂管理,Spring只是帮我们调用了静态工厂创建实例的方法,而实际的创建过程在静态工厂方法中。
- 通过实例工厂方法创建
目标类提供一个实例工厂方法(需先定义实例工厂Bean),把创建实例的工厂类userFactory交给Spring管理,创建实例的过程由配置的实例工厂userFactory内部实现,Spring管理调用实例工厂类的方法进行实例创建。
以上内容为个人学习汇总,仅供学习参考,如有问题,欢迎在评论区指出,谢谢!