. IOC 容器管理各层的组件
. 使用 AOP 配置声明式事务
. 整合其他框架
Bean 的配置方式:
通过全类名(反射)
通过工厂方法(静态工厂方法 & 实例工厂方法)
FactoryBean
FactoryBean定义
package org.springframework.beans.factory;
public interface FactoryBean {
T getObject() throws Exception;
Class> getObjectType();
boolean isSingleton();
}
FactoryBean 通常是用来创建比较复杂的bean,一般的bean 直接用xml配置即可, 但如果一个bean的创建过程中涉及到很多其他的bean 和复杂的逻辑,用xml配置比较困难,这时可以考虑用FactoryBean。
. 通过构造器或工厂方法创建 Bean 实例
. 为 Bean 的属性设置值和对其他 Bean 的引用
. 将 Bean 实例传递给 Bean 前置处理器的postProcessBeforeInitialization 方法
. 调用 Bean 的初始化方法(init-method)
. 将 Bean 实例传递给 Bean 后置处理器的postProcessAfterInitialization 方法
. Bean 可以使用了
. 当容器关闭时, 调用 Bean 的销毁方法(destroy-method)
在整个 Spring MVC 框架中, DispatcherServlet 处于核心位置,负 责协调和组织不同组件以完成请求处理并返回响应的工作。
SpringMVC 处理请求过程:
. @RequestMapping 、@PathVariable 、@RequestParam 、@RequestBoy 、
. @ResponseBody
. 配置MappingJacksonHttpMessageConverter
. 使用 @ResponseBody 注解或 ResponseEntity 作为返回值
. ResponseEntity 可以定义返回的HttpHeaders和HttpStatus
. 使用@RestController修饰控制器(Spring MVC 4)
@RequestBody
处理HttpEntity传递过来的数据,一般用来处理非Content-Type: application/x-www-form-urlencoded编码格式的数据。 GET请求中,因为没有HttpEntity,所以@RequestBody并不适用。 POST请求中,通过HttpEntity传递的参数,必须要在请求头中声明数据的类型Content-Type,SpringMVC通过使用HandlerAdapter 配置的HttpMessageConverters来解析HttpEntity中的数据,然后绑定到相应的bean上。
@Autowired与@Resource、@Qualifier
@Resource装配顺序
主要区别
1、SpringBoot自动配置原理
参考
2、SpringCloud Config properties属性加载分析
上 下
3、SpringBoot解决循环依赖
循环依赖的解决
Resource //资源文件的抽象,xml 、 properties ...
BeanDefinition //bean的抽象定义 (bean的一些基本信息是否是 抽象、单例、懒加载、作用域...)基本信息
BeanDefinitionReader //不同的资源文件的bean的解析
BeanFactory //bean工厂的顶层抽象定义了几个基础的方法 getBean() contanisBean() ....
ApplicationContext //应用程序上下文
步骤:
1、继承AbstractRoutingDataSource路由
2、ThreadLocal存数据源
3、构建数据源并初始化
4、指定主库 @Primary
5、AOP拦截注解+注解标记方法
在对象内部的方法中调用该对象的其他使用AOP机制的方法,被调用方法的AOP注解失效。
在一个类的A方法中调用同类的B方法,实际上使用的是使用实例调用方式this.B(),而代理对象是$开头的一个对象,此时的调用并不会走代理,注解会无效。 因为在被代理对象的方法中调用被代理对象的其他方法时。其实是没有用代理调用,是用了被代理对象本身调用的。
newProxyInstance 产生一个代理对象 ,三个参数
1.classloader 代理对象和被代理对象应该处于同一个 classloader
2.接口产生的代理对象应该实现哪些接口
3.handel 执行代理对象方法时,应用哪个handel 处理。
(接口中有什么方法,代理中就有什么方法 代理中的每个方法在调用的时候都会把方法自身传给 handel, 并把代理对象和参数都传递过去 )
静态代理:由程序员或者自动生成工具生成代理类,然后进行代理类的编译和运行。在代理类、委托类运行之前,代理类已经以.class的格式存在。
动态代理:在程序运行时,由反射机制动态创建而成。(各种字节码操纵工具以及框架可以实现)
. JDK动态代理只能对实现了接口的类生成代理,而不能针对没有实现接口的类
. CGLIB是针对类实现代理,主要是对指定的类生成一个子类,覆盖其中的方法,因为是继承,所以该类或方法最好不要声明成final
动态代理设计模式类图
动态代理宏观图
连接ASM部分
补充模糊查询
SQL注入漏洞测试:原文:http://www.cnblogs.com/leftshine/p/SQLInjection.html#downloadFile
还有很多其他的标签,
,加上动态sql的9个标签,trim|where|set|foreach|if|choose|when|otherwise|bind等,其中
为sql片段标签, 通过
标签引入sql片段,
为不支持自增的主键生成策略标签。
Dao接口,就是人们常说的Mapper接口,接口的全限名,就是映射文件中的namespace的值,接口的方法名,就是映射文件中MappedStatement的id值, 接口方法内的参数,就是传递给sql的参数。Mapper接口是没有实现类的,当调用接口方法时,接口全限名+方法名拼接字符串作为key值,可唯一定位一个MappedStatement, 举例:com.mybatis3.mappers.StudentDao.findStudentById,可以唯一找到namespace为com.mybatis3.mappers.StudentDao下面id = findStudentById的MappedStatement。 在Mybatis中,每一个 标签,都会被解析为一个MappedStatement对象。 Dao接口里的方法,是不能重载的,因为是全限名+方法名的保存和寻找策略。 Dao接口的工作原理是JDK动态代理,Mybatis运行时会使用JDK动态代理为Dao接口生成代理proxy对象,代理对象proxy会拦截接口方法,转而执行MappedStatement所代表的sql,然后将sql执行结果返回。
Mybatis使用RowBounds对象进行分页,它是针对ResultSet结果集执行的内存分页,而非物理分页,可以在sql内直接书写带有物理分页的参数来完成物理分页功能,也可以使用分页插件来完成物理分页。 分页插件的基本原理是使用Mybatis提供的插件接口,实现自定义插件,在插件的拦截方法内拦截待执行的sql,然后重写sql,根据dialect方言,添加对应的物理分页语句和物理分页参数。 举例:select * from student,拦截sql后重写为:select t.* from (select * from student)t limit 0,10
Mybatis动态sql可以让我们在Xml映射文件内,以标签的形式编写动态sql,完成逻辑判断和动态拼接sql的功能,Mybatis提供了9种动态sql标签trim|where|set|foreach|if|choose|when|otherwise|bind。 其执行原理为,使用OGNL从sql参数对象中计算表达式的值,根据表达式的值动态拼接sql,以此来完成动态sql的功能。
Mybatis仅支持association关联对象和collection关联集合对象的延迟加载,association指的就是一对一,collection指的就是一对多查询。在Mybatis配置文件中,可以配置是否启用延迟加载lazyLoadingEnabled=true|false。 它的原理是,使用CGLIB创建目标对象的代理对象,当调用目标方法时,进入拦截器方法,比如调用a.getB().getName(),拦截器invoke()方法发现a.getB()是null值,那么就会单独发送事先保存好的查询关联B对象的sql,把B查询上来, 然后调用a.setB(b),于是a的对象b属性就有值了,接着完成a.getB().getName()方法的调用。这就是延迟加载的基本原理。 当然了,不光是Mybatis,几乎所有的包括Hibernate,支持延迟加载的原理都是一样的。
如果我们一般插入数据的话,如果我们想要知道刚刚插入的数据的主键是多少,我们可以通过以下的方式来获取 通过LAST_INSERT_ID()获取刚插入记录的自增主键值,在insert语句执行后,执行select LAST_INSERT_ID()就可以获取自增主键。
select LAST_INSERT_ID()
INSERT INTO USER(username,birthday,sex,address) VALUES(#{username},#{birthday},#{sex},#{address})
第一种:使用占位符的思想
在映射文件中使用#{0},#{1}代表传递进来的第几个参数,使用@param注解:来命名参数
第二种:使用Map集合作为参数来装载,根据key自动找到对应Map集合的value
PS:由于一直使用SpringBoot、SpringCloud,对于SSM没有过多研究,主要是根据网络和自己的经历整理的。仅供参考
转自:jxnu-liguobin
https://github.com/jxnu-liguobin/Java-Learning-Summary