BeanFactory,Spring中的BeanFactory就是简单工厂模式的实现,根据传入一个唯一的标识来获得Bean对象。实质,由一个工厂类根据传入的参数,动态决定应该创建哪些产品类。
典型的例子就是PropertyPlaceHolderConfigurer,一般在配置数据库的dataSource时使用到的占位符的值,就是它注入进去的。
CGLib (Code Generation Library) 是一个强大的、高性能、高质量的 Code 生成类库。它可以在运行期扩展 Java 类与实现 Java 接口。Hibernate 用它来实现 PO 字节码的动态生成。CGLib 比 Java 的 java.lang.reflect.Proxy 类更强的在于它不仅可以接管接口类的方法,还可以接管普通类的方法。
JDK和CGLIB动态代理的区别
实例化阶段主要是通过反射或者CGLIB对bean进行实例化,在这个阶段Spring又暴露出很多的扩展点:
可以将原来硬编码的依赖,通过Spring的BeanFactory这个工厂来注入依赖,也就是原来只有依赖方和被依赖方。现在引入了第三方——Spring的BeanFactory,由它来解决bean之间的依赖关系,达到了松耦合。
通过Spring暴露的接口,在实例化Bean的阶段,可以进行一些额外的处理,这些处理只需要让bean实现对应的接口即可,那么Spring就在在bean的生命周期调用我们实现的接口来处理改bean。
Bean 的生命周期
FactoryBean接口
BeanFactory和FactoryBean的区别
实现了FactoryBean接口的bean是一类叫做factory的bean。其特点是,spring会在使用getBean()调用获得该bean时,会自动调用该bean的getObject()方法,所以返回的不是factory这个bean,而是这个bean.getOjbect()方法的返回值。
代码示例(Spring和Mybatis的结合)
<bean class="org.mybatis.spring.SqlSessionFactoryBean" id="sessionFactory">
<property name="dataSource" ref="dataSource">property>
<property name="configLocation" value="classpath:mybatis-config-xml">property>
<property name="mapperLocations" value="classpath:com/mapper/*.xml">property>
bean>
Spring依赖注入Bean实例默认是单例的。Spring的依赖注入(包括Lazy-init方式)都是发生在AbstractBeanFactory的getBean里。getBean的doGetBean方法调用getSingleton进行bean的创建.spring依赖注入时,使用了 双重判断加锁 的单例模式.
**单例模式定义:**保证一个类仅有一个实例,并提供一个访问它的全局访问点。
Spring中的单例模式,提供了全局访问点BeanFactory,但没有从构造器级别去控制单例,这是因为Spring管理的是任意的JAVA对象。
指在不改变原有对象的基础上,将功能附加到对象上,比继承更加灵活。
Spring中用到的包装器模式在类名上有两种表现,一种是类名中,含有Wrapper,另一种是含有Decorator。
**适用场景:**动态地给一个对象添加一些额外的职责,就功能来说,Decorator模式相比生成子类更为灵活。
**适用场景:**扩展一个类的功能或给一个类添加附加职责;动态给一个对象添加功能,这些功能可以再动态的撤销;在生活中,给煎饼加鸡蛋、蛋糕加水果、房子装修等都是在为对象扩展一些额外的职责。
**辅助编程(AOP )是指面向切面编程:**通过预编译方式和运行期动态代理实现程序功能的统一维护的一种技术。AOP 是 OOP 的延续,是软件开发中的一个热点,也是 Spring 框架中的一个重要内容,是函数式编程的一种衍生范型。利用AOP 可以对业务逻辑的各个部分进行隔离,从而使得业务逻辑各部分之间的耦合度降低,提高程序的可重用性,同时提高了开发的效率。
Aop 在 Spring 中的作用 提供声明式事务;允许用户自定义切面 横切关注点:跨越应用程序多个模块的方法或功能。即是,与我们业务逻辑无关的,但是我们需要 关注的部分,就是横切关注点。如日志 , 安全 , 缓存 , 事务等等 … 切面( ASPECT ):横切关注点 被模块化 的特殊对象。即,它是一个类。 通知( Advice ):切面必须要完成的工作。即,它是类中的一个方法。 目标( Target ):被通知对象。 代理( Proxy ):向目标对象应用通知之后创建的对象。 切入点( PointCut ):切面通知 执行的 “ 地点 ” 的定义。 连接点( JointPoint ):与切入点匹配的执行点。
AOP底层就是动态代理的实现。作用:动态代理作用:功能增强和控制访问
既然动态代理是AOP实现,那么动态代理的角色必须与AOP相同。 也就是说,它主要用于方法的扩展。 这样,可以在不修改源代码的情况下扩展方法,并在方法执行前后做任何想做的事情。 因为InvocationHandler的invoke方法可以直接访问调用该方法的Method方法
在内存构建中,不需要手动编写代理类
需要手动编写代理类,代理类引用被代理对象。
切面在应用运行的时刻被织入,一般情况下,在织入切面时,AOP容器会为目标对象动态的创建一个代理对象。
织入:把切面应用到目标对象并创建新的代理对象的过程。
自定义需要发布的事件类,需要继承 ApplicationEvent 类或 PayloadApplicationEvent (该类也仅仅是对 ApplicationEvent 的一层封装)
使用 @EventListener 来监听事件或者实现 ApplicationListener 接口。
使用 ApplicationEventPublisher 来发布自定义事件(@Autowired注入即可)
@TransactionalEventListener 监听器:如果事件的发布不是在事务(@Transactional)范围内,则监听不到该事件,除非将 fallbackExecution 标志设置为 true(@TransactionalEventListener(fallbackExecution = true));如果在事务中,可以选择在事务的哪个阶段来监听事件,默认在事务提交后监听(@TransactionalEventListener(phase = TransactionPhase.AFTER_COMPLETION))
Spring的事件驱动模型使用的是观察者模式,Spring中Observer模式常用的地方是listener的实现。
Spring中观察者模式的四个角色
1.事件(ApplicationEvent)
ApplicationEvent 是所有事件对象的父类。ApplicationEvent 继承自 jdk 的 EventObject, 所有的事件都需要继承 ApplicationEvent, 并且通过source得到事件源。
下列描述了Spring提供的内置事件:
2.事件监听(ApplicationListener)
ApplicationListener 事件监听器,也就是观察者。继承自 jdk 的 EventListener,该类中只有一个方法 onApplicationEvent。当监听的事件发生后该方法会被执行。
3.事件发布(ApplicationContext)
ApplicationContext 是 Spring 中的核心容器,在事件监听中 ApplicationContext 可以作为事件的发布者,也就是事件源。因为 ApplicationContext 继承自 ApplicationEventPublisher。在 ApplicationEventPublisher 中定义了事件发布的方法 — publishEvent(Object event)
4.事件管理(ApplicationEventMulticaster)
ApplicationEventMulticaster 用于事件监听器的注册和事件的广播。监听器的注册就是通过它来实现的,它的作用是把 Applicationcontext 发布的 Event 广播给它的监听器列表。
事件机制的实现需要三部分(事件源、事件、事件监听器)
ApplicationEvent抽象类【事件】:继承自JDK的EventObject,所有的事件都需要继承ApplicationEvent,并且通过构造器参数source得到事件源。该类的实现类ApplicationContextEvent表示ApplicationContext的容器事件。这个接口只有一个onApplicationEvent()方法。该方法接受一个ApplicationEvent或者其它子类对象作为参数,在方法体中,可以通过不同Event类的判断进行相应的处理。当事件触发时所有的监听器都会收到消息。
public abstract class ApplicationEvent extends EventObject {
/**
* Constructs a prototypical Event.
*
* @param source The object on which the Event initially occurred.
* @throws IllegalArgumentException if source is null.
*/
public ApplicationEvent(Object source) {
super(source);
}
}
ApplicationContext是spring中的全局容器,翻译过来是”应用上下文”。 实现了ApplicationEventPublisher接口。
观察者模式:定义对象间一种一对多的依赖关系,使得每当一个对象改变状态,则所有依赖它的对象都会得到通知并自动更新。此设计模式最重要的作用就是解耦!将观察者与被观察者解耦,使得他们之间的依赖性更小。
比如说对象的某个行为,在不同场景中有不同的实现方式,这样就可以将这些实现方式定义为一组策略,每个实现类对应一个策略,在不同的场景就使用不同的实现类,从而实现自由切换策略。当程序中使用太多的if/else/switch来处理不同类型的业务时,会变得极难维护,通过策略模式可以更容易的实现业务扩展和维护。
父类定义了骨架(调用哪些方法及顺序),某些特定方法由子类实现。最大的好处:代码复用,减少重复代码。除了子类要实现的特定方法, 其他方法及方法调用顺序都在父类中预先写好了。
所以父类模板方法中有两类方法:
**共同的方法:**所有子类都会用到的代码
**不同的方法:**子类要覆盖的方法,分为两种:
抽象方法:父类中的是抽象方法,子类必须覆盖
钩子方法:父类中是一个空方法,子类继承了默认也是空的
Spring模板方法模式实质:
是模板方法模式和回调模式的结合,是Template Method不需要继承的另一种实现方式。Spring几乎所有的外接扩展都采用这种模式。
spring和SpringMVC的联系和区别
spring&springMVC 他两属于父子关系
spring是粘合剂,是容器。它主要作用是粘合其他模块组件,进行统一管理
Springmvc是spring扩展出的一个应用于Web端的框架
spring框架核心
IOC(控制反转):传统的过程中,当某个对象依赖于另外一个对象,会有该对象去创建另外一个对象,但是有了IOC之后,将创建过程交给IOC
AOP(面向切面的编程)
Spring MVC新特性
提供了对Restful风格的支持
@GetMapping,处理get请求
@PostMapping,处理post请求
@PutMapping,处理put请求
@DeleteMapping,处理delete请求
SpringMVC中的适配器HandlerAdatper
HandlerAdatper根据Handler规则执行不同的Handler。
DispatchServlet根据HandlerMapping返回的Handler,向Handler发起请求,处理Handler.
HandleAdatper根据规则找到对应的Handler并让其执行,执行完毕后Handler会向HandlerAdaptper返回一个ModelAndView,最后由HandlerAdaptper想DispatchServlet返回一个ModelAndView。
实现意义
HandlerAdaptper是的Handler的扩展变得容易,只需要增加一个新的Handler和一个对应的HandlerAdaptper即可。所以Spring定义了一个适配接口,使得每一种Controller有一种对应的适配器实现类。让适配器代替controller执行相应的方法,这样在扩展Controller时,只需要增加一个适配器类就完成了SpringMVC的扩展。