一、概述:
java是一个分层的JavaEE级的开发的开源框架
- WEB层:SpringMVC
- 业务层:Spring的IoC
- 持久层:Spring的JDBCTemplate(Spring的JDBC模板,ORM模板用于整合其他的持久层框架)
二、好处:
- spring对现有的主流的框架进行了支持。
- spring降低了各个组件之间的耦合性,实现了软件各层之间的解耦。
- spring的模块虽然多,但是也高度开发过的,并不请强行依赖于Spring,开发着可以自由的选择需要的组件。
三、模块:
- spring Core 核心容器
- spring Aop 面向切面
- spring Dao JDBC的封装
- spring ORM ORM框架的集成
- Spring Context 上下文,是一个配置文件
- Spring Web 基于Web的应用程序提供了上下文,web层使用web框。
- Spring MVC web程序的一个mvc框架的实现。
四、IOC的理解:
- IOC就是控制反转,把创建对象权反转给spring,由容器来创建和维护对象之间的依赖关系,降低了程序耦合性。而非在传统实现中,对象由程序代码直接创建,控制权由程序代码的本身,转到了外部的spring容器,由容器根据配置文件创建和维护对象之间的依赖关系。
- DI 就是依赖注入,实例化对象的时候主动的将他依赖的对象注入给调用的对象。例如:A对象有个成员变量B对象。 在实例化A的时候,自动的将B对象入住。
IOC的三种注入方式:
- 属性注入,也叫setter注入。
- 构造注入。
- 根据注解注入。
beanFactory是springIOC容器的具体实现与核心。
五、BeanFactory和ApplicationContext的区别:
beanFactory和ApplicationContext都是spring的两大核心接口,而其中ApplicationContext是BeanFactory的子接口。他们都可以作为springIOC容器,实例化并管理容器中的bean。
-
BeanFactory是spring的最底层的接口,它提供了容器最简单的功能,负责读取配置文件,实例化bean,并维护bean的生命周期。但无法支持Aop功能和web功能。
-
ApplicationContext接口是BeanFactory的字节口,拥有BeanFactory的所有功能,并且还提供了更多的功能。
bean的实例化:
BeanFactory采用延迟加载的方式来注入bean,就是在具体使用到某个bean的时候,才对bean进行实例化。这样就不能及时的发现spring中存在的配置问题,如果Bean的某一个属性没有注入,BeanFacotry加载后,直至第一次使用调用getBean方法才会抛出异常
ApplicationContext和BeanFactory相反。他是在容器启动的时候,就一次性的实例化所有bean。这样,在容器启动时,我们就可以发现Spring中存在的配置错误,这样有利于检查所依赖属性是否注入。springBean的Id属性:
springBean中的id属性是bean的标识,在Ioc容器中,可以根据Id查找bean,是不能重复的。
可以不指定id属性,但要写全类名。如果找不到bean,就抛异常:NoSuchBeanDefinitionException如果该类型的Bean有多个则抛异常:NoUniqueBeanDefinitionException
如果不指定id,只制定name,那么,name就是标识符并且需要在容器中唯一,如果同时指定Id和name,此时id为标识列,而name为bean的别名。两者都可以找到bean。Spring bean的作用域:
- singleton:单例模式,是的默认值,不管多少个请求,每个容器中就只有一个bean的实例化对象。
- prototype: 多例模式,每次从容器中调用bean时都是一个新的对象。
- request: 每次http请求都会创建一个新的bean,该作用于适用于webApplicationContext环境。
- session:同一个HttpSession共享一个bean,该作用于适用于swebApplicationContext环境。
- global session:同一个HttpSession共享一个bean,与session不同的是,全部session公用一个bean。
springBean的生命周期:
-
spring容器读取xml中的bean,并实例化bean.
-
spring根据bean的定义设置属性值。
-
如果该bean实现了beanNameAware接口,spring将bean的id传递给setBeanName(id);方法。
-
如果bean实现了beanFactoryAware接口,spring将beanFactory传递给setBeanFactory(beanFactory)方法。
-
如果Bean实现了ApplicationContextAware接口,会调用setApplicationContext(ApplicationContext);
-
如果这个bean关联了beanPostProcessor接口,将会调用PostProcessorBeforeInitalization(Object obj, String s);方法,BeanPostProcessor经常被用作是Bean内容的更改,并且由于这个是在Bean初始化结束时调用那个的方法,也可以被应用于内存或缓存技术;
-
如果bean在配置中文件中配置了init-method实行会自动调用配置的初始化方法。
-
如果这个Bean关联了BeanPostProcessor接口,将会调用postProcessAfterInitialization(Object obj, String s)方法、;
-
当Bean不再需要时,会经过清理阶段,如果Bean实现了DisposableBean这个接口,会调用那个其实现的destroy()方法;
-
最后,如果这个Bean的Spring配置中配置了destroy-method属性,会自动调用其配置的销毁方法。
在一个bean被实例化的时候,需要执行一系列的初始化操作以达到可用的状态,同样的当bean不再使用的时候,需要进行相关的销毁操作,把bean从容器中移除。spring bean factory负责管理spring容器中bean的生命周期。 初始化方法回调方法,和销毁之前的回调方法,针对特殊的行为的Aware接口。
单例beans是线程安全的吗?
spring并没有对单列bean进行任何的多线程安全处理,关于多线程安全和并发问题需要开发者自己进行维护,实际上,大部分的bean,并mei’you可变的状态(Service类,Dao类),所以在某种程度上来说spring的单例bean是线程安全的。
如果你的bean是多种状态的(view model)对象,就需要自行保证线程的安全。最简单的方式就是将多态的bean的作用域设置成多例的。
六、spring的自动装配:
属性的自动装配:
在spring框架中共有5中自动装配:bean标签的autowire属性。
- no: 这是pring框架的默认设置,在该设置下,自动装配是关闭的,开发着需要在配置文件bean标签中明确依赖关系。
- byType:该选项是根据bean的类型类进行自动装配的。当向一个bean中自动装配一个属性时,容器将根据bean的类型自动在在配置文件中查询一个匹配的bean。如果找到的话,就装配这个属性,如果没找到的话就报错。
- ByName:该选项是根据类的名称进行自动装配。当向一个bean中自动装配一个属性时,容器将根据bean名称自动在配置文件中查询一个可以匹配的bean,如果不存在,就报错。
constructor:构造器的自动装配和byType模式类似,但是仅仅适用于与有构造器相同参数的bean,如果在容器中没有找到与构造器参数类型一致的bean,那么将会抛出异常.- autodetect :该模式自动探测使用构造器自动装配或者byType自动装配。首先,首先会尝试找合适的带参数的构造器,如果找到的话就是用构造器自动装配,如果在bean内部没有找到相应的构造器或者是无参构造器,容器就会自动选择byTpe的自动装配方式。
局限性:
你仍需用 constructor-arg和 property标签 配置来定义依赖,意味着总要重写自动装配。你不能自动装配简单的属性,如基本数据类型,String字符串,和类。自动装配不如显式装配精确,如果有可能,建议使用显式装配,或注解的方式装配
七、spring Aop:
概述:
Aop:面向切面编程,可以说是OOP的补充和完善。OOP允许开发者定义纵向的关系,但并不适合定义横向的关系。OOP引入封装、继承、多态等概念来建立一种对象层次结构,而Aop是横向重复的功能纵向抽取,比如,我们的日志功能。。
Aop的核心概念:
关注点:对哪些方法进行拦截,拦截后怎么处理,这些关注点称之为横切关注点
目标对象:被代理的对象。
连接点:目标对象中,所有可以被增强的方法。
通知:增强的代码。通知分为前置、后置、异常、最终、环绕通知五类
切入点:已经被增强的方法。
织入:将通知应用到切入点的过程
切面:切入点,+通知。
AOP 和 代理模式:
代理模式:
分为静态代理和动态代理,动态代理又分为JDK动态代理和cglib动态代理。Aop的底层就是用动态代理实现的,其将动态代理进行封装,方便是使用。
静态代理:
在编译期间就写好的代理类,在编译期间就确定了耦合关系。
优点: 扩展原功能,不侵入原代码。
缺点:会重复创建多个逻辑相同,仅仅RealObject引用不同的Proxy。
动态代理:
在运行期间来确定代理对象实际的业务和额外的新功能。
JDK动态代理:要求业务类必须有接口,没有接口无法生成代理对象。通过反射进行invoke回调
Cglib动态代理:不需要业务类必须有接口,有实现类也可,底层采用asm字节码生成框架生成代理类的字节码,它创建慢,但一旦创建要比jdk方式快。cglib使用继承,因此父类最好不要有final属性,final阻止继承和多态。
优点:
静态代理,每一个业务都对应一个静态的代理对象。
动态代理,InvocationHandler的子实现的复用率高。
缺点:
实际业务类里的所有的方法都要添加额外的功能,不能实现只给部分方法添加额外的功能。
八、spring注解
概述:
基于Java的配置,允许你在少量的Java注解的帮助下,进行你的大部分Spring配置而非通过XML文件。
以@Configuration 注解为例,它用来标记类可以当做一个bean的定义,被Spring IOC容器使用。另一个例子是@Bean注解,它表示此方法将要返回一个对象,作为一个bean注册进Spring应用上下文。
开发者通过在相应的类,方法或属性上使用注解的方式,直接组件类中进行配置,而不是使用xml表述bean的装配关系。
开启注解 <context:annotation-config />
属性的自动装配:
@Autuwired(required=false):按类型自动装配,不支持id匹配。required属性:false,对象可以为null;true,对象必须存对象,不能为null。
@Qualifier: 不能单独使用。@Autowired是根据类型自动装配的,加上@Qualifier则可以根据byName的方式自动装配。
@Resource:如有指定的name属性,先按该属性进行byName方式查找装配;其次再进行默认的byName方式进行装配;如果以上都不成功,则按byType的方式自动装配。都不成功,则报异常。
类自动装配:
@Controller注解 只能用控制器类上
@Service注解 只能用在业务类上
@Repository注解 只能用在dao类上
@Component注解 组件,无法按照上面三个注解分类,就用此注解
常用注解:
@Controller
@Service 声明service组件
@Repository 声明Dao组件
@Component 泛指之间,不好归类时使用
@RequestMapping 请求映射
@Resource 用于注入,默认按名称装配
@Autowired 用于注入,默认按类型装配
@Transactional 事务管理
@ResponseBody
@Scope 设置bean的作用域
九、管理spring中事务
事务:
对于一个操作,要么都做,要么都不做,不可分割的一个逻辑工作单位。
特性:
- 原子性:要么都做,要么都不做。
- 一致性:操作前和操作后的数据总量是一直的。
- 隔离性:一个事务执行的时候,可能被另一个事务所打扰。
- 持久性:一旦提交,对数据的改变是永久性的。
事务的隔离级别:
- 读未提交: 引发脏读,不可重复度,幻读
- 读已提交:引发不可重复度,幻读
- 可重读:引发幻读
- 可串行化:最高级别,没问题。
spring支持编程式事务管理和声明式事务管理两种方式:
DataSource、TransactionManager这两部分只是会根据数据访问方式有所变化,
比如使用Hibernate进行数据访问 时,DataSource实际为SessionFactory,TransactionManager的实现为 HibernateTransactionManager。
根据不同的数据源和数据访问方式,创建事务管理器。
编程式事务侵入到了业务代码里面,但是提供了更加详细的事务管理;而声明式事务由于基于AOP,所以既能起到事务管理的作用,又可以不影响业务代码的具体实现。
十、 spring中使用的设计模式:
单例模式:在spring配置文件中定义的bean默认是单列的。
工厂模式:BeanFactory用来创建对象的实例。
代理模式:在Aop中用到的较多。
依赖注入:也是一种设计模式,让对象的实例化和使用分离。
十一、springMVC:
概述:
springMVC是spring家族提供的一个web层的优秀的MVC框架,是目前最流行的MVC框架。
springMVC的执行流程:
- 用户发送一个请求到前端控制器,
- 前端控制器接收到请求后,调用处理器映射器。获取处理器和处理器拦截器,返回前端控制器。
- 前端控制器通过处理器适配器调用处理器。
- 执行处理器,并把返回的结果ModelAndView返回给前控制器。
- 前端控制器调用视图解析器解析ModelAndView,返回View对象。
springMVC和struts2比较:
- springMVC是以一个Servlet,及dispatcherServlet 前端控制器为入口,而struts2是以filter为入口。
- springMVC是基于方法开发的,请求参数与方法形参映射,可以设计为单例也可以设计为多例。struts2基于类开发的,只能设置为单例。
总结:
以前struts2基于类开发的,定义属性可以整个类通用,所以默认是多例的,不然多线程共用里面的属性,造成线程安全问题,而springMVC是基于方法开发的,参数使用方法的形参来接收,方法执行完毕后,形参也就销毁了,里面的参数不会共用,所以一般情况下,springMVC默认的单例模式就是线程安全的,
springMVC怎么设定重定向和转发:
在方法的返回值前加forward(转发)和 redirect(重定向);
springMVC中拦截器怎么写:
- 实现Handlerinterceptor接口。
- 继承适配器类。
如何解乱码问题:
Post请求:
加入characterEncodingFilter过滤器。
get请求:
- 修改tomcat的配置文件编码一致。
- String?userName =?new?String(request.getParamter
(“userName”).getBytes(“ISO8859-1”),“utf-8”)
ISO8859-1是tomcat默认编码,需要将tomcat编码后的内容按utf-8编码
springMVC的异常处理:
抛给spring,让spring框架来处理,我们只需要配置简单的异常处理器。
SpingMvc中的控制器的注解一般用那个,有没有别的注解可以替代?
一般用@Controller注解,表示是控制层,不能用用别的注解代替。
@RequestMapping注解用在类上面有什么作用?
是一个用来处理请求地址映射的注解,可用于类或方法上。用于类上,表示类中的所有响应请求的方法都是以该地址作为父路径
…
SpringMVC怎么和AJAX相互调用的?
通过Jackson框架就可以把Java里面的对象直接转化成Js可以识别的Json对象。
方法上添加@ResponseBody 返回JSON。