Spring
AOP
面向切面编程,使用”横切”技术,AOP把软件系统分为两个部分:核心关注点和横切关注点。业务处理的主要流程是核心关注点,与业务逻辑关系不大的部分是横切关注点。横切关注点经常发生在核心关注点的多处,而各处基本相似,比如权限认证、日志、事务管理等。
AOP基于代理模式,动态代理 :AOP框架不会去修改字节码,而是每次运行时在内存中临时为方法生成aop对象.aop对象包含目标的全部方法,并在特定切点进行增强处理,然后回调原对象.
Spring AOP中的动态代理主要有两种方式,JDK动态代理和CGLIB动态代理
动态代理
JDK动态代理是基于Java的反射机制实现的,主要涉及到java.lang.reflect包中的Proxy和InvocationHandler。
InvocationHandler是一个接口,通过实现这个接口定义一个横切的逻辑!然后通过反射机制调用目标类的方法,这样就能动态的把非业务逻辑和业务逻辑动态的拼接在一起.
proxy则利用InvocationHandler创建代理实例,来间接的调用代理的方法!
JDK的反射是基于接口的!也就是你的service一定是有接口的不然是不行的!这时候就有个Cglib可以顶上了!
Cglib采用了底层的字节码技术,为代理类创建了一个子类来代理它!
简单实现
1 |
|
插入日志功能
1 |
|
知识点
spring优点:低侵入,IOC低耦合,AOP对日志安全等通用应用统一管理,高复用.
IOC是什么,控制反转,让对象创建不用去new.由spring通过反射机制根据配置文件在运行时动态创建对象.spring提供4种集合配置,如:list,set,map,props(双string的map)
事务
Spring 事务传播
required:没有就创建,存在就加入
supports:存在就加入,不存在就不做事务
mandatory:存在就加入,不存在就抛异常
requires_new:不管是否存在都新建
no_supported:如果存在事务将事务挂起.
nerver:存在事务我就抛异常.
nested:存在就嵌套,不存在就创建
事务隔离级别:
default:默认db级别
read_uncommitted:读取未提交(会脏读),基本不用
read_committed:读取已提交(会幻读,不可重复读)
repeatable_read:可重复读,行锁(会幻读)
serializable:完全看不到其他事务的操作,表锁
解释Spring支持的几种bean的作用域。
1 | Spring框架支持以下五种bean的作用域: |
Spring实现原理
Spring是实现了工厂模式的工厂类。这个类名为BeanFactory(实际上是一个接口),在程序中通常BeanFactory的子类ApplicationContext。Spring相当于一个大的工厂类,在其配置文件中通过
IOC,IOC就是一个容器,负责实例化、定位、配置应用程序中的对象及建立这些对象间的依赖。很好地实现模块之间的解耦,@Autowired,不用每次去new service。
AOP面向切面,如:系统中有很多各不相干的类的方法,在这些众多方法中要加入某种系统功能的代码(是否能理解是类似于中间件),例如,加入日志,加入权限判断,加入异常处理,Transactions事务,Synchronization同步
实现AOP功能采用的是代理技术,客户端程序不再调用目标,而调用代理类,代理类与目标类对外具有相同的方法声明,有两种方式可以实现相同的方法声明,一是实现相同的接口,二是作为目标的子类。
Spring框架的好处
容器:Spring 包含并管理应用中对象的生命周期和配置。
MVC框架:Spring的WEB框架是个精心设计的框架,是Web框架的一个很好的替代品。
事务管理:Spring 提供一个持续的事务管理接口,可以扩展到上至本地事务下至全局事务(JTA)。
异常处理:Spring 提供方便的API把具体技术相关的异常(比如由JDBC,Hibernate or JDO抛出的)转化为一致的unchecked 异常。
ApplicationContext通常的实现是什么?
FileSystemXmlApplicationContext :此容器从一个XML文件中加载beans的定义,XML Bean 配置文件的全路径名必须提供给它的构造函数。
ClassPathXmlApplicationContext:此容器也从一个XML文件中加载beans的定义,这里,你需要正确设置classpath因为这个容器将在classpath里找bean配置。
WebXmlApplicationContext:此容器加载一个XML文件,此文件定义了一个WEB应用的所有bean。
什么是Spring beans
Spring beans 是那些形成Spring应用的主干的java对象。它们被Spring IOC容器初始化,装配,和管理。这些beans通过容器中配置的元数据创建。比如,以XML文件中
Spring 框架定义的beans都是单件beans。在bean tag中有个属性”singleton”,如果它被赋为TRUE,bean 就是单件,否则就是一个 prototype bean。默认是TRUE,所以所有在Spring框架中的beans 缺省都是单件。
Spring框架中bean的生命周期
Spring容器从XML 文件中读取bean的定义,并实例化bean
Spring根据bean的定义填充所有的属性
如果bean实现了BeanNameAware 接口,Spring 传递bean 的ID 到 setBeanName方法;
如果Bean 实现了 BeanFactoryAware 接口, Spring传递beanfactory 给setBeanFactory 方法。
如果有任何与bean相关联的BeanPostProcessors,Spring会在postProcesserBeforeInitialization()方法内调用它们。
如果bean实现IntializingBean了,调用它的afterPropertySet方法,如果bean声明了初始化方法,调用此初始化方法。
如果有BeanPostProcessors 和bean 关联,这些bean的postProcessAfterInitialization() 方法将被调用。
如果bean实现了 DisposableBean,它将调用destroy()方法。
SpringMVC的原理
Spring MVC的核心就是 DispatcherServlet , 一个请求经过 DispatcherServlet ,转发给HandlerMapping ,然后经反射,对应 Controller及其里面方法的@RequestMapping地址,最后经ModelAndView和ViewResoler返回给对应视图 。

springmvc拦截器的定义和配置
1 | //测试拦截器1 |
- preHandle方法:进入Handler方法之前执行。可以用于身份认证、身份授权。比如如果认证没有通过表示用户没有登陆,需要此方法拦截不再往下执行(return false),否则就放行(return true)。
- postHandle方法:进入Handler方法之后,返回ModelAndView之前执行。可以看到该方法中有个modelAndView的形参。应用场景:从modelAndView出发:将公用的模型数据(比如菜单导航之类的)在这里传到视图,也可以在这里同一指定视图。
- afterCompletion方法:执行Handler完成之后执行。应用场景:统一异常处理,统一日志处理等。
BeanFactory和ApplicationContext有什么区别?
BeanFactory和ApplicationContext是Spring的两大核心接口,都可以当做Spring的容器。其中ApplicationContext是BeanFactory的子接口。
(1)BeanFactory:是Spring里面最底层的接口,包含了各种Bean的定义,读取bean配置文档,管理bean的加载、实例化,控制bean的生命周期,维护bean之间的依赖关系。ApplicationContext接口作为BeanFactory的派生,除了提供BeanFactory所具有的功能外,还提供了更完整的框架功能:
①继承MessageSource,因此支持国际化。
②统一的资源文件访问方式。
③提供在监听器中注册bean的事件。
④同时加载多个配置文件。
⑤载入多个(有继承关系)上下文 ,使得每一个上下文都专注于一个特定的层次,比如应用的web层。
①BeanFactroy采用的是延迟加载形式来注入Bean的,即只有在使用到某个Bean时(调用getBean()),才对该Bean进行加载实例化。这样,我们就不能发现一些存在的Spring的配置问题。如果Bean的某一个属性没有注入,BeanFacotry加载后,直至第一次使用调用getBean方法才会抛出异常。
②ApplicationContext,它是在容器启动时,一次性创建了所有的Bean。这样,在容器启动时,我们就可以发现Spring中存在的配置错误,这样有利于检查所依赖属性是否注入。 ApplicationContext启动后预载入所有的单实例Bean,通过预载入单实例bean ,确保当你需要的时候,你就不用等待,因为它们已经创建好了。
③相对于基本的BeanFactory,ApplicationContext 唯一的不足是占用内存空间。当应用程序配置Bean较多时,程序启动较慢。
(3)BeanFactory通常以编程的方式被创建,ApplicationContext还能以声明的方式创建,如使用ContextLoader。
(4)BeanFactory和ApplicationContext都支持BeanPostProcessor、BeanFactoryPostProcessor的使用,但两者之间的区别是:BeanFactory需要手动注册,而ApplicationContext则是自动注册。
Autowired与Resource
使用@Autowired注解来自动装配指定的bean。在使用@Autowired注解之前需要在Spring配置文件进行配置,<context:annotation-config />。在启动spring IoC时,容器自动装载了一个AutowiredAnnotationBeanPostProcessor后置处理器,当容器扫描到@Autowied、@Resource或@Inject时,就会在IoC容器自动查找需要的bean,并装配给该对象的属性。在使用@Autowired时,首先在容器中查询对应类型的bean:
如果查询结果刚好为一个,就将该bean装配给@Autowired指定的数据;
如果查询的结果不止一个,那么@Autowired会根据名称来查找;
如果上述查找的结果为空,那么会抛出异常。解决方法时,使用required=false。
@Autowired可用于:构造函数、成员变量、Setter方法
注:@Autowired和@Resource之间的区别
(1) @Autowired默认是按照类型装配注入的,默认情况下它要求依赖对象必须存在(可以设置它required属性为false)。
(2) @Resource默认是按照名称来装配注入的,只有当找不到与名称匹配的bean才会按照类型来装配注入。