一、spring ApplicationContextAware使用
关于ApplicationContextAware,这是个接口,作用是实现了该接口的类,在Spring初始化的时候,会去执行该接口唯一的方法 setApplicationContext(),这个方法你要自己去实现,一般是用来将web的上下文(ApplicationContext)填充到 指定的static变量,方便你以后在其他地方使用(以后你要用这个上下文获得bean,可直接调用),所以,通常实现这个接口的类是个工具类,用来获取 bean实例。
ApplicationEventPublisher接口。Spring中与事件有关的接口和类主要包括ApplicationEvent、ApplicationListener。
ApplicationContext具有发布事件的能力。这是因为该接口继承了个事件的类需要继承ApplicationEvent或者ApplicationContextEvent抽象类,该抽象类中只有一个构造函数,并 且带有一个Object类型的参数作为事件源,并且该事件源不能为null,因此我们需要在自己的构造函数中执行super(Object)。
二、新建maven web工程的方法
1.File – 》New -》maven project
2.选择工作空间
3. Next, 选择“maven-archetype-webapp”创建一个webapp目录结构的项目
4. 填Group Id,Artifact Id,和Package(请参考后面的“关键词”),点击“Finish”
Maven仓库代码提示找不到contextloaderListener
- 右键单击工程项目 ->点击 properties
2. 选择 Deployment Assembly
3. 点击 Add -> Java Build Path Entries -> Next
4. 选择 Maven Dependencies -> Finish -> Apply -> OK
5. Clean project and server. 重启server
三、SpringMvc+ajax 实现json格式数据传递
传JSON对象
前端
function test () {
var param = {username : "yitop"};
$.ajax({
timeout : 20000,
type : "POST",
dataType : "JSON",
url : "/user/userRole.htm",
data : param,
success : function(data){
alert(data);
}
//注意:这里不能加下面这行,否则数据会传不到后台
//contentType:'application/json;charset=UTF-8',
});
}
后端
Controller:
@RequestMapping(value = "userRole", method = RequestMethod.POST)
@ResponseBody
public List<Role> selectRoles(String username) throws WebTransException {
/* 逻辑代码 */
}
传JSON字符串+@RequestBody接收,之前使用@RequestBody接收json数据总是报400或者415
前端
function icheckDelete(url){
var parms = {
list : array //这是个数组
};
$.ajax({
dataType: "JSON",
contentType:'application/json;charset=UTF-8',//关键是要加上这行
traditional:true,//这使json格式的字符不会被转码
data: JSON.stringify(parms),
type: "DELETE",
timeout: 20000,
url: url,
success : function () {
alert("删除成功!");
},
error : function (data){
alert(data.responseText);
}
});
}
后端
Controller:
@RequestMapping(value = "deleteList", method = RequestMethod.DELETE)
@ResponseBody
public String delete(@RequestBody DeleteListRequest request) throws WebTransException{
/* 逻辑代码 */
return "success";
}
Springmvc 返回html页面
在web.xml中,
增加
<servlet-mapping>
<servlet-name>default</servlet-name>
<url-pattern>*.html</url-pattern>
</servlet-mapping>
四、@Autowired注解不起作用?
<!-- 使用annotation 自动注册bean, 并保证@Required、@Autowired的属性被注入 -->
<context:component-scan base-package="com.yuanls"/>
五、FactoryBean
首先要分辨BeanFactory 与 FactoryBean的区别, 两个名字很像,所以容易搞混
BeanFactory: 以Factory结尾,表示它是一个工厂类,是用于管理Bean的一个工厂
FactoryBean:以Bean结尾,表示它是一个Bean,不同于普通Bean的是:它是实现了FactoryBean<T>接 口的Bean,根据该Bean的Id从BeanFactory中获取的实际上是FactoryBean的getObject()返回的对象,而不是 FactoryBean本身, 如果要获取FactoryBean对象,可以在id前面加一个&符号来获取
六、maven引用本地jar
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-support</artifactId>
<version>3.1.0.RELEASE</version>
</dependency>
Maven 安装 JAR 包的命令是:
mvn install:install-file -Dfile=jar包的位置 -DgroupId=上面的groupId -DartifactId=上面的artifactId -Dversion=上面的version -Dpackaging=jar
2. 将jar包安装到本地repository中
mvn install:install-file -Dfile=my-jar.jar -DgroupId=org.richard -DartifactId=my-jar -Dversion=1.0 -Dpackaging=jar
3. 添加 in project repository,在新机器上执行时就不用运行mvn install:install-file命令了
<repository>
<id>in-project</id>
<name>In Project Repo</name>
<url>file://${project.basedir}/lib</url>
</repository>
<dependency>
<groupId>org.richard</groupId>
<artifactId>my-jar</artifactId>
<version>1.0</version>
</dependency>
你的jar包及路径必须严格遵循格式:
/groupId/artifactId/version/artifactId-verion.jar
本例中: lib/org/richard/my-jar/1.0/my-jar-1.0.jar
七、通过ObjectFactory解决循环依赖
只有单例的情况才会解决循环依赖
objectFactory中getObject方法返回的可能是代理的bean,或者是未完全初始化完的bean, objectFactory封装了对象的创建过程
八、httpMessageConvert 消息转换
这个消息转换只有在增加了注解@requestBody 和 @responseBody才会起作用
具体进行数据处理时
PropertyEditor 属性编辑器,字符串和jvm能识别类型之间的转换
ConversionService 数据类型转换,格式化
九、ThreadLocal
线程池中使用TheadLocal注意内存泄漏的问题,每个thread中都存在一个map, map的类型是ThreadLocal.ThreadLocalMap. Map中的key为一个threadlocal实例. 这个Map的确使用了弱引用,不过弱引用只是针对key. 每个key都弱引用指向threadlocal. 当把threadlocal实例置为null以后,没有任何强引用指向threadlocal实例,所以threadlocal将会被gc回收. 但是,我们的value却不能回收,因为存在一条从current thread连接过来的强引用. 只有当前thread结束以后, current thread就不会存在栈中,强引用断开, Current Thread, Map, value将全部被GC回收.
十、spring容器和springMvc容器的关系
配置前端控制器,会在spring容器中创建一个新的容器,也就是springmvc这个容器,springmvc中存的是 controller,spring中存的是service,dao。日常开发过程中,spring中将dao注入到service中,因为它们在一个容 器中,注入没有问题,当然我们将service注入到controller中使用Autowired 注入也没有问题,这是因为子容器是可以访问父容器中的对象,而在spring容器中父容器是不能访问子容器的对象的,这个时候如果我们配了一个全局的注解 扫描,容器会将service,dao,controller都放到spring容器中,而springmvc容器中没有对象,也就没有 controller,当其在加载前端控制器的时候找不到controller对象。
我们可以使用统一的如下注解配置来对Bean进行批量注册,而不需要再给每个Bean单独使用xml的方式进行配置。
<context:component-scan base-package="com.hafiz.www" />
从Spring提供的参考手册中我们得知该配置的功能是扫描配置的base-package包下的所有使用了@Component注解的类,并 且将它们自动注册到容器中,同时也扫描@Controller,@Service,@Respository这三个注解,因为他们是继承自 @Component。
在项目中我们经常见到还有如下这个配置,其实有了上面的配置,这个是可以省略掉的,因为上面的配置会默认打开以下配置。以下配置会默认声明了 @Required、@Autowired、 @PostConstruct、@PersistenceContext、@Resource、@PreDestroy等注解。
另外,还有一个和SpringMVC相关如下配置,经过验证,这个是SpringMVC必须要配置的,因为它声明了@RequestMapping、@RequestBody、@ResponseBody等。并且,该配置默认加载很多的参数绑定方法,比如json转换解析器等。
<mvc:annotation-driven />
十一、DelegatingFilterProxy的作用
DelegatingFilterProxy就是一个对于servlet filter的代理,用这个类的好处主要是通过Spring容器来管理servlet filter的生命周期,还有就是如果filter中需要一些Spring容器的实例,可以通过spring直接注入,另外读取一些配置文件这些便利的操作都可以通过Spring来配置实现。
DelegatingFilterProxy的使用方法,
首先在web.xml中配置:
<filter>
<filter-name>myFilter</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>
<filter-mapping>
<filter-name>myFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
然后在Spring的配置文件中,配置具体的Filter类的实例。
<bean name="myFilter" class="com.*.MyFilter"></bean>
在Spring中配置的bean的name要和web.xml中的<filter-name>一样
或者在DelegatingFilterProxy的filter配置中配置初始参数:targetBeanName,对应到Spring配置中的beanname
如果要保留Filter原有的init,destroy方法的调用,还需要配置初始化参数targetFilterLifecycle为true,该参数默认为false
十二、RequestContextListener的作用
在整合spring容器时使用ContextLoaderListener,它实现了ServletContextListener监听器接口,ServletContextListener只负责监听web容器启动和关闭的事件。
而RequestContextListener实现ServletRequestListener监听器接口,该监听器监听HTTP请求事件,web服务器接收的每一次请求都会通知该监听器。
spring容器启动和关闭操作由web容器的启动和关闭事件触发,但如果spring容器中的Bean需要 request,session,globalsession作用域的支持,spring容器本身就必须获得web容器的HTTP请求事件,以HTTP请 求的事件”驱动”Bean作用域的控制逻辑。
十三、OpenSessionInViewFilter的作用及原理
Hibernate 允许对关联对象、属性进行延迟加载,但是必须保证延迟加载的操作限于同一个 Hibernate Session 范围之内进行。如果 Service 层返回一个启用了延迟加载功能的领域对象给 Web 层,当 Web 层访问到那些需要延迟加载的数据时,由于加载领域对象的 Hibernate Session 已经关闭,这些导致延迟加载数据的访问异常
(eg: org.hibernate.LazyInitializationException:(LazyInitializationException.java:42)
- failed to lazily initialize a collection of role: cn.easyjava.bean.product.ProductType.childtypes, no session or session was closed
org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: cn.easyjava.bean.product.ProductType.childtypes, no session or session was closed)。
把一个Hibernate Session和一次完整的请求过程对应的线程相绑定。目的是为了实现"Open Session in View"的模式。例如: 它允许在事务提交之后延迟加载显示所需要的对象。
OpenSessionInViewFilter 过滤器将 Hibernate Session 绑定到请求线程中,它将自动被 Spring 的事务管理器探测到。所以 OpenSessionInViewFilter 适用于 Service 层使用HibernateTransactionManager 或 JtaTransactionManager 进行事务管理的环境,也可以用于非事务只读的数据操作中。
十四、产融前端下载模板是直接前端保存了模板文件excel文件,并不是后端通过代码生成的模板文件
十五、getResourceAsStream使用规则
首先,Java中的getResourceAsStream有以下几种:
1. Class.getResourceAsStream(String path) : path 不以’/'开头时默认是从此类所在的包下取资源,以’/'开头则是从ClassPath根下获取。其只是通过path构造一个绝对路径,最终还是由 ClassLoader获取资源。
2. Class.getClassLoader.getResourceAsStream(String path) :默认则是从ClassPath根下获取,path不能以’/'开头,最终是由ClassLoader获取资源。
十六、jdbcTemplate和mybatis事务
这两者采用相同的事务管理器,都是jdbc提供的事务管理器,因为代码中将这两者混用不用担心事务管理的问题
ean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource" />
</bean>
但hibernate使用的事务管理器是TransactionManager用的是HibernateTransactionManager
因此hibernate和mybatis混用的时候就要小心事务管理的问题了,获取事务连接不会存在问题,主要是hibernate具有一级缓存,如果不注意会产生问题
十七、知识点
1)springmvc进行对象封装的时候(例如由json到对象的映射),会调用对象的get和set方法
2)同一个session中,如果执行了数据库的更新或者插入操作,但没有提交commit,同一个session中是可以获取到最新的数据的
3) 1、服务器如何判断客户端发送过来的请求是属于同一个会话?
答:用Session id区分,Session id相同的即认为是同一个会话,在Tomcat中Session id用JSESSIONID表示;
2、服务器、客户端如何获取Session id?Session id在其之间是如何传输的呢?
答:服务器第一次接收到请求时,开辟了一块Session空间(创建了Session对象),同时生成一个Session id,并通过响应头的Set-Cookie:“JSESSIONID=XXXXXXX”命令,向客户端发送要求设置cookie的响应;
客户端收到响应后,在本机客户端设置了一个JSESSIONID=XXXXXXX的cookie信息,该cookie的过期时间为浏览器会话结束;
接下来客户端每次向同一个网站发送请求时,请求头都会带上该cookie信息(包含Session id);
然后,服务器通过读取请求头中的Cookie信息,获取名称为JSESSIONID的值,得到此次请求的Session id;
ps:服务器只会在客户端第一次请求响应的时候,在响应头上添加Set-Cookie:“JSESSIONID=XXXXXXX”信息,接下来在同一个会话的第二第三次响应头里,是不会添加Set-Cookie:“JSESSIONID=XXXXXXX”信息的;
而客户端是会在每次请求头的cookie中带上JSESSIONID信息;
十八、servlet,filter,listener
很明显的可以看出对于Servlet的Filter我们都需要配置url,而对于Listener则不需要,它是针对对象的。
另外web.xml 的加载顺序是:context- param -> listener -> filter -> servlet
十九、会话保持
二十、大表UUID如果作为主键,插入时对性能影响比较大
二十一
ShardingJdbc
垂直拆分:行的属性比较多,一行的数据量比较大,把这个表(库)的不同属性拆分成不同的表(库)
特点:1)表(库)结构都不一样 2)表(库)含有相同的列,不同的表(库)的并集是全量数据
水平拆分:按照表(库)中的某个字段取模,将数据路由到不同的表或者库
策略:
Hash取模
Range范围区分
List预定义
带来的问题:
多数据源的管理(proxy)、跨库事务处理(避免XA 2pc)TCC柔弱性事务、查询数据的结果合并(改写)、分布式全局唯一id
遵循ACID前提下提高我们的并行能力
Kafka吞吐量比较大,可能会丢数据
二十二、jdk
concurrentHashMap segment +table,两层hash
读是不需要加锁,通过tableEntity中的很多域是final类型的,其中value为volatile类型,可以保证happen-before原则\
XA/JTA
XA两阶段提交协议
JTA实现了XA协议的接口
二十三、tomcat配置jndi
Context.xml中增加如下配置内容:
<Resource name="A_xxfpserverdb" type="javax.sql.DataSource"
driverClassName="com.ibm.db2.jcc.DB2Driver" url="jdbc:db2://99.12.74.65:50001/tmsdb"