社区微信群开通啦,扫一扫抢先加入社区官方微信群
社区微信群
额外的延伸点
:
既controller可以访问dao,service,而dao,service无法访问controller
,就是说可以以下犯上,但是不可以倚老卖老bean的生命周期
ApplicationContext相比BeanFactory的优化
:
BeanFatoryPostProcessor接口
,作用在于初始化bean之前,先会通过这些工厂后处理器对
配置信息进行加工处理,如有:CustomEditorConfigurer,反射技术自动识别出定义的BeanPostProcessor,InstantiationAwareBeanPostProcessor和BeanPostProcessor
并且自定注册到容器中,而BeanFactory则需要通过代码手动注册(addBeanPostProcessor)既在ApplicationContext中只需要要将实现BeanPostProcessor接口的类标志为bean即可,他加载过后会自动扫描的
)bean自身的方法
:
bean级生命周期接口
: 针对的是bean对象
容器级生命周期接口:
: 针对的是所有的bean,既所有的bean都会执行某种操作,当然也可以自编写后置处理器,使得只对特殊的bean感兴趣,全局性的
工厂后置处理器
: 既实现了BeanFactoryPostProcessor接口的类,当加载完配置文件之后立马会调用wip待完善
wip
专门用于web,允许从web的根目录文件中装载配置文件从而初始化
,可以获得ServletContext的引用
wip
)初始化上下文的时候就加载了所有的bean信息
可以通过DefaultListableBeanFactory动态注入
,当然其实也是可以通过BeanPostProcessor扫描让后发现指定注解之后生成代理类代替的BeanFactoryPostProcessor接口
WIP
- 前者是心脏,后者是一个完整的人
- 关于生命周期,记住核心的一个:
BeanPostProcessor这个接口,aop的功能就是通过他来实现的,如果我们想创建工具,或者aop中通过this 使得aop|事务生效可以通过这个借口来实现代理
- BeanFactory是只有
初次getBean的时候才会注册bean
,而ApplicationContext是初始化的时候就会加载所有的bean
- bean生命周期中的关于destroy-method和init-method 其实这是对于xml配置而言的,而对于JavaConfig而言就是@PostConstruct和@PreDestroy,既
init-method=@PostConstruct;destroy-method=@PreDestroy
事件源
: 既EventObject内部有一个object的source对象,代表源对象,每个EventObject必须有一个source对象事件监听器注册表
: 既保存事件的容器,当事件发生的时候就会notify这些监听器事件广播器
: 既通知监听器执行任务,起到桥梁的作用事件类
(ApplicationEvent): 通过内部的source指定事件源
可以发现顶级类是AppEvent,
启动
,刷新
,停止
,关闭
事件只有在web.xml中定义了DispatcherServlet时才会产生该事件
事件接口
:
EventListener
SmartApplicationListener
接口3.0新增: 作用: 只会针对于某些特定类型的事件做出响应
,通过boolean supportsEventType(Class<? extends ApplicationEvent> event)判断GenericApplicationListener
4.2新增,不再仅仅只支持ApplicationEvent,既事件不再需要继承ApplicationEvent,直接泛型即可,原理就是通过boolean supportsEventType(ResolveType type) 这个ResolveType可以获取到泛型的实际类型信息
事件广播器
:
ApplicationEventMulticaster
其抽象类为: AbstarctApplicationEventMuliticaster 其子类为SimpleApplicationEventMulticaster如何使用呢:
这一步可以没有,如果没有的话会默认使用SimpleApplicationEventMulticaster
)当然这一步我们是可以直接使用的的,不过这样的话,第二步中就不应该是实现ApplicationListener了,而是继承GenericApplicationListener然后复写supportsEventType来特指这个泛型了
核心就是
- 事件源:EventObject
- 事件处理者(监听器对象): EventListener (但我们
大多直接使用ApplicationListener即可
)- 事件广播器: 顶级是ApplicationListenerMulticaster (
这个我们一般不需要去自定义,如果无自定义,Spring默认会使用SimpleApplicaitonListenerMulticaster
)
Bean配置信息在ioc容器中需要存在这些信息:
bean在ioc容器中是以BeanDefinition
的形式存在的,IOC容器+Bean实现类+Bean配置信息+应用程序的关系如图:
流程为: 编写配置
->启动容器->扫描配置类,生成beanDefinitionRegistry注册所有的beanDefinition
->通过beaDefinition实现具体的类
->将生成的bean放到缓存池中(ioc容器)
bean配置中有用的点:
parent属性的作用
:,这点在实际项目中遇到过,因为命令模式模板模式往往要抽象类的作用,每个命令都是bean,多了肯定会冗余,因而parent的作用就体现了:
bean的模式: 单例(singleton,prototype)模式,如果使用的是WebApplicationContext则还有(request,session)等模式
<bean id="parentObserver"
class="com.dlxy.config.DlxyObservervable">
<property name="obs">
<list>
<ref bean="userRecordObserver" />
</list>
</property>
</bean>
<bean id="userWrappedService"
class="com.dlxy.service.impl.UserWrappedServiceImpl"
parent="parentObserver" />
<bean id="titleWrappedServie"
class="com.dlxy.service.impl.TitleWrappedServiceImpl"
parent="parentObserver" />
<bean id="articleWrappedservice"
class="com.dlxy.service.impl.ArticleWrappedServiceObservableImpl"
parent="parentObserver" />
<bean id="pictureWrappedService"
class="com.dlxy.service.impl.PictureWrappedServiceObservableImpl"
parent="parentObserver" />
这样通过parent属性,就不需要为每个bean都单独的设置list中的属性了
什么是servletContext
: ServletContext 是一个全局的类,可以认为是共享的数据区
ServletContext的作用
: 存放公共配置类,既在<web.xml>中由 < context-param>标签包裹的数据,当然这里额外延伸一点配置问题
:
<context-param></context-param>
这种方式可以通过getServletContext().getInitParameter("param1")获取值,
并且是共享的,所有的servlet都可以访问
<init-param>
<param-name>param1</param-name>
<param-value>avalible in servlet init()</param-value>
</init-param>
只能在servlet中通过this.getInitParameter("param1")获取
ServletContext何时初始化
: 当Servlet容器第一次启动的时候就会实例化一个ServletContext
如何使用
: 可以通过ServletContextAware接口获取到SerletContext的引用,并且由此我们可以发现Spring设计上的一个特点,Aware接口
什么是WebApplicationContext
:
什么是WebApplicationContext
: WebApplicationContext是ApplicationContext的一个子类,这是专门为Web准备的,为何这么说,它多了额外的属性:bean的scope属性:如request,session等
,其顶级接口又是BeanFactory,因而可以认为是ioc容器
,webApplicationContext无法更通俗理解,它有多个实现类,其中有XmlWebApplicationContext和AnnotationConfigWebApplicationContextWebApplicationContext的作用:
很明显,既是BeanFactory的作用,作用是存放所有的bean
何时初始化
: 当servlet执行init方法之后,会触发ContextLoadListener,在ContextLoadListener中会初始化WebApplicationContext(通过event.getServletContext())共有数据
,存放Servlet间共享的数据可以这么理解:先后问题和职责问题:
数据共享,存放所有的配置信息
,那么所有bean 的引用当然要存放在这咯ThreadLocal
面向切面编程
,竖线逻辑上插入就是类中的所有方法都是连接点
连接点的细分
,并不是所有的连接点都会是切点,只会针对特定的连接点作为切点(既进行额外的加工)编译期
提供横切代码的逻辑,有一个专门的编译器和特殊的类加载器运行期
通过代理方式增强,侧重于ico与aop的结合反射
WIP:代码演示
WIP:代码演示
适用性
:cglib更加适用,jdk基于接口,既被代理的类必须有实现的接口才可以,而cglib则是衍生出子类来实现代理
原理
:jdk是反射
,cglib原理是字节码技术
性能
上cglib性能更高完全可以抽出接口来简化编程
,Spring有如下增强类:
范围最广,不仅能充当前置,后置,也能充当异常抛出增强
)WIP:代码演示
setOptimize(true)会启用优化代理,这样就算是接口也会是使用cglib
切面是切点+增强类型
StaticMethodMatcherPointcut
是静态方法切点的抽象基类,
WIP待补,怎么进行匹配的待补
动态方法切点
: DynamicMethodMatcherPointcut ,是抽象基类WIP待补,同上
注解切点
: AnnotationMatchingPointcut: 支持在bean中通过注解标签定义的切点表达式切点
: ExpressionPointcut接口 ,为了支持AspectJ切点表达式语法而定义的接口流程切点
: WIP
复合切点
: ComposablePointcut 为创建多个切点而提供的方便操作类,WIP需要配合代码理解,虽然可以简单的认为与以前的想法一致
切面类型的分类:
Advisor
: 一般切面,仅仅只是包含了Advice(增强类型)PointcutAdvisor
: 代表的是具有切点的切面
,包含Advice和Pointcut2个类
IntroductionAdvisor
: 代表引介切面
,对应的advisor是引介增强类型添加切面
横切代码
和连接点的信息(包含了这个类的所有方法)增强类型
: 增强类型是指 前置增强(BeforeAdvice)还是后置增强(AfterReturningAdvice)还是环绕增强等(既发生增强所处的时机)切面
是切点+增强类型注意
:<context-param>
<param-name>contextClass</param-name>
<param-value>org.springframework.web.context.support.AnnotationConfigWebApplicationContext
</context-param>
然后对于原先的contextConfigLocation则是指向具体的类
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>com.test.config.Configuraiton</param-value>
</context-param>
当然你不指定也是没关系的,只要通过 <component-scan basepackages="com.demo">
这样讲配置类扫描进去也是可以的,但是注意要与SpringMVC的配置扫描分开哦,不然会加载两次,血的教训
在web.xml中配置:
,至于作用在上面已经申明了
<listener>
<listener-class>org.springfarmework.web.context.ContextLoadListener</listener-class>
</listener>
这个listener可以获取到<context-param>中的名为contextConfigLocation的值,
至于这个值是可以采用统配符的: classpath:*/spring-*.xml
如:
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/spring-mvc.xml</param-value>
</context-param>
注意:
放置在contextConfigListener之前
load-on-startup要设置为1
,优先级别最高<context-param>
<param-name>log4jConfigLocation</param-name>
<param-value>/WEB-INF/log4j.properties</param-value>
</context-param>
<listener>
<listener-class>Log4jConfigListener</listener-class>
</listener>
<servlet>
<servlet-name>log4jConfigSerlvet</servlet-name>
<serlvet-class>org.springframework.web.util.Log4jConfigServlet</servet-class>
<load-on-startup>1</load-on-startup>
</servlet>
wip:key是什么类型
,当然有一大堆配置类,配置类线性结构,通过order排序,然后顺序调用单例的长生命周期的对象
,因而都会开放其Aware接口,用于开发者获取其引用,如ApplicaitonContextAware接口,ServletContextAware接口,因而,在我们以后的设计中也大可以这样通过aware接口获取长生命周期框架对象的引用
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!