spring

18.7.22
属性注入和构造器注入区别
Spring也同时支持两种依赖注入方式:设值注入和构造注入。 这两种依赖注入的方式,并没有绝对的好坏,只是适应的场景有所不同。相比之下,设值注入有如下优点:
1、设值注入需要该Bean包含这些属性的setter方法
2、与传统的JavaBean的写法更相似,程序开发人员更容易理解、接收。通过setter方法设定依赖关系显得更加只管。
3、对于复杂的依赖关系,如果采用构造注入,会导致构造器国语臃肿,难以阅读。Spring在创建Bean实例时,需要同时实例化器依赖的全部实例,因而导致性能下降。而使用设值注入,则能避免这些问题
4、尤其是在某些属性可选的情况况下,多参数的构造器显得更加笨重

构造注入也不是绝对不如设值注入,在某些特定的场景下,构造注入比设值注入更加优秀。构造注入有以下优势:

    1、构造注入需要该Bean包含带有这些属性的构造器
    2、构造注入可以在构造器中决定依赖关系的注入顺序,优先依赖的优先注入。例如,组件中其他依赖关系的注入,常常要依赖于DataSrouce的注入。采用构造注入,可以在代码中清晰的决定注入顺序。
    3、对于依赖关系无需变化的Bean,构造注入更有用处。因为没有Setter方法,所有的依赖关系全部在构造器内设定。因此,无需担心后续的代码对依赖关系产生破坏。
    4、依赖关系只能在构造器中设定,则只有组件的创建者才能改变组件的依赖关系。对组件的调用者而言,组件内部的依赖关系完全透明,更符合高内聚的原则。

建议:采用以设值注入为主,构造注入为辅的注入策略。对于依赖关系无需变化的注入,尽量采用构造注入;而其他的依赖关系的注入,则考虑采用设值注入。

参考:https://blog.csdn.net/sdx1237/article/details/59173172
————————————
18.6.7
1、过滤器
过滤器依赖于servlet容器。在实现上基于函数回调,可以对几乎所有请求进行过滤,但是缺点是一个过滤器实例只能在容器初始化时调用一次。使用过滤器的目的是用来做一些过滤操作,获取我们想要获取的数据,比如:在过滤器中修改字符编码;在过滤器中修改HttpServletRequest的一些参数,包括:过滤低俗文字、危险字符等

在web.xml中配置过滤器
<filter>
<description>字符集过滤器</description>
<filter-name>encodingFilter</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>UTF-8</param-value>
</init-param>
<init-param>
<param-name>forceEncoding</param-name>
<param-value>true</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>encodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>

以上是一个已有过滤器,配置使用。
还可以自定义过滤器,实现Filter接口,实现三个方法:
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain)
public void destroy()
public void init(FilterConfig arg0) throws ServletException
doFilter最好需要调用filterChain.doFilter(req, res);继续过滤链。

在spring中,filter都默认继承OncePerRequestFilte,OncePerRequestFilter顾名思义,他能够确保在一次请求只通过一次filter,而不需要重复执行。
源码里其实是对请求和回应进行过滤了。
if (!(request instanceof HttpServletRequest) || !(response instanceof HttpServletResponse)) {
throw new ServletException("OncePerRequestFilter just supports HTTP requests");
}
在servlet-2.3中,Filter会过滤一切请求,包括服务器内部使用forward转发请求和<%@ include file="/index.jsp"%>的情况。
到了servlet-2.4中Filter默认下只拦截外部提交的请求,forward和include这些内部转发都不会被过滤,但是有时候我们需要 forward的时候也用到Filter。
因此,为了兼容各种不同的运行环境和版本,默认filter继承OncePerRequestFilter是一个比较稳妥的选择。

Filter有一系列的抽象或实现,见https://blog.csdn.net/liangxw1/article/details/51095484

参考:https://blog.csdn.net/MissEel/article/details/79351231
http://ully.iteye.com/blog/1334925

2、监听器:
它也是随web应用的启动而启动,只初始化一次,随web应用的停止而销毁。主要作用是:做一些初始化的内容添加工作、设置一些基本的内容、比如一些参数或者是一些固定的对象等等。
它是实现了javax.servlet.ServletContextListener 接口的服务器端程序。

2 <listener>
3 <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
4 </listener>
——

2 <listener>
3 <listener-class>com.kingdee.opensys.common.util.ReadPropertiesListener</listener-class>
4 </listener>
——
public class ReadPropertiesListener implements ServletContextListener{
5
6 public void contextDestroyed(ServletContextEvent sce) {
7 // TODO Auto-generated method stub
8
9 }
10
11 public void contextInitialized(ServletContextEvent sce) {
12 // TODO Auto-generated method stub
13 String path = sce.getServletContext().getRealPath("/WEB-INF/config/common.properties");
14 PropertiesUtils.init(path);
15 }
16
17 }
——

2 <context-param>
3 <param-name>log4jConfigLocation</param-name>
4 <param-value>/WEB-INF/classes/config/log4.properties</param-value>
5 </context-param>
6
7 <listener>
8 <listener-class>org.springframework.web.util.Log4jConfigListener</listener-class>
9 </listener>

参考:https://www.cnblogs.com/youzhongmin/p/6940418.html

3、过滤器与拦截器的区别
1)过滤器:

依赖于servlet容器。在实现上基于函数回调,可以对几乎所有请求进行过滤,但是缺点是一个过滤器实例只能在容器初始化时调用一次。使用过滤器的目的是用来做一些过滤操作,获取我们想要获取的数据,比如:在过滤器中修改字符编码;在过滤器中修改HttpServletRequest的一些参数,包括:过滤低俗文字、危险字符等

拦截器:

依赖于web框架,在SpringMVC中就是依赖于SpringMVC框架。在实现上基于Java的反射机制,属于面向切面编程(AOP)的一种运用。由于拦截器是基于web框架的调用,因此可以使用Spring的依赖注入(DI)进行一些业务操作,同时一个拦截器实例在一个controller生命周期之内可以多次调用。但是缺点是只能对controller请求进行拦截,对其他的一些比如直接访问静态资源的请求则没办法进行拦截处理
testFilter1
testFilter2
BaseInterceptor
TestInterceptor

图片.png

图片.png

参考:https://blog.csdn.net/xiaoyaotan_111/article/details/53817918
——————————
18.5.30
1、@RequestParam和@PathVariable 区别。
(1)@RequestParam针对URI如下格式的:
url = “{ctx}/main/mm/am/edit?Id={Id}&name={name}” 一定要有键值对 可以这么用: @RequestMapping("/edit") public String edit(Model model, @RequestParam Map paramMap ) {long id = Long.parseLong(paramMap.get("id").toString());} 也可以这么用: User printUser(@RequestParam(value = "id", required = false, defaultValue = "0") int id){} (2)@PathVariable针对URI如下格式的: url = “{ctx}/main/mm/am/edit/{Id}/{name}”
没有键值对
只能这么用:
RequestMapping("/edit/{id}/{name}")
public String edit(Model model, @PathVariable long id,@PathVariable String name) {}

参考:https://www.cnblogs.com/helloworld-hyyx/p/5295514.html
https://www.cnblogs.com/hq233/p/7146264.html
——————————
18.5.14
1、spring拦截器
Java里的拦截器是动态拦截action调用的对象。它提供了一种机制可以使开发者可以定义在一个action执行的前后执行的代码,也可以在一个action执行前阻止其执行,同时也提供了一种可以提取action中可重用部分的方式。

实现HandlerInterceptor接口,实现几个方法,配置到<Bean>或者加个注解,就实现了一个拦截器。
在mvc:interceptors标签中,有两种类型的配置,一种直接配置一个bean(bean和ref归为一类),另一种还要配置上拦截的路径和排除的路径。
前者代表对所有的请求进行拦截,而后者带有mvc:interceptor则代表有着更精细的控制。
注册全部url到拦截器:
<mvc:interceptors>
<bean class="org.springframework.web.servlet.i18n.LocaleChangeInterceptor" />
</mvc:interceptors>
An example of registering an interceptor limited to a specific URL path:
注册指定url到拦截器:
<mvc:interceptors>

<mvc:interceptor>
<mvc:mapping path="/" />
<mvc:exclude-mapping path="/static/
" /> //判处拦截的url
<bean class="拦截器java代码路径" />
</mvc:interceptor>
</mvc:interceptors>

preHandle,SpringMVC中的Interceptor拦截器是链式的,可以同时存在多个Interceptor,
然后SpringMVC会根据声明的前后顺序一个接一个的执行,
而且所有的Interceptor中的preHandle方法都会在Controller方法调用之前调用。
SpringMVC的这种Interceptor链式结构也是可以进行中断的,
这种中断方式是令preHandle的返回值为false,当preHandle的返回值为false的时候整个请求就结束了。

postHandle,这个方法只会在当前这个Interceptor的preHandle方法返回值为true的时候才会执行。
postHandle是进行处理器拦截用的,它的执行时间是在处理器进行处理之 后, 也就是在Controller的方法调用之后执行,但是它会在DispatcherServlet进行视图的渲染之前执行,也就是说在这个方法中你可以对ModelAndView进行操作。这个方法的链式结构跟正常访问的方向是相反的,也就是说先声明的Interceptor拦截器该方法反而会后调用,这跟Struts2里面的拦截器的执行过程有点像,只是Struts2里面的intercept方法中要手动的调用ActionInvocation的invoke方法,Struts2中调用ActionInvocation的invoke方法就是调用下一个Interceptor或者是调用action,然后要在Interceptor之前调用的内容都写在调用invoke之前,要在Interceptor之后调用的内容都写在调用invoke方法之后。

afterCompletion,该方法也是需要当前对应的Interceptor的preHandle方法的返回值为true时才会执行。该方法将在整个请求完成之后,也就是DispatcherServlet渲染了视图执行, 这个方法的主要作用是用于清理资源的。

执行顺序:
===========HandlerInterceptor1 preHandle
===========HandlerInterceptor2 preHandle
===========TestController
===========HandlerInterceptor2 postHandle
===========HandlerInterceptor1 postHandle
==========test.jsp
===========HandlerInterceptor2 afterCompletion
===========HandlerInterceptor1 afterCompletion

对于以上三个方法的参数Object handler,相当于响应的处理器(如Controller实现),
可能的使用如下:
if (handler instanceof HandlerMethod) {
HandlerMethod handlerMethod = (HandlerMethod) handler;
System.out.println("[a-preHandle]>>>请求控制器名称:" + handlerMethod.getBean().getClass().getName());
System.out.println("[a-preHandle]>>>请求方法名称:" + handlerMethod.getMethod().getName());
}

常见应用场景
1、日志记录:记录请求信息的日志,以便进行信息监控、信息统计、计算PV(Page View)等。
2、权限检查:如登录检测,进入处理器检测检测是否登录,如果没有直接返回到登录页面;
3、性能监控:有时候系统在某段时间莫名其妙的慢,可以通过拦截器在进入处理器之前记录开始时间,在处理完后记录结束时间,从而得到该请求的处理时间(如果有反向代理,如apache可以自动记录);
4、通用行为:读取cookie得到用户信息并将用户对象放入请求,从而方便后续流程使用,还有如提取Locale、Theme信息等,只要是多个处理器都需要的即可使用拦截器实现。
5、OpenSessionInView:如Hibernate,在进入处理器打开Session,在完成后关闭Session。
…………本质也是AOP(面向切面编程),也就是说符合横切关注点的所有功能都可以放入拦截器实现。

spring提供了一个空的HandlerInterceptorAdapter实现了HandlerInterceptor。就不用必须实现三个方法了。

参考:https://www.sohu.com/a/128772280_523754
https://www.cnblogs.com/super-chao/p/6496428.html
https://blog.csdn.net/tong_xinglong/article/details/52035131
https://www.cnblogs.com/nizuimeiabc1/p/7717531.html
https://zhidao.baidu.com/question/629424828579600284.html
http://jinnianshilongnian.iteye.com/blog/1670856/
http://jinnianshilongnian.iteye.com/blog/1670856

2、web.xml中的contextConfigLocation
在web.xml中通过contextConfigLocation配置spring,
contextConfigLocation参数定义了要装入的 Spring 配置文件。
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:applicationContext.xml</param-value>
</context-param>
如果没有指定路径,默认会去/WEB-INF/下加载applicationContext.xml。

如果想装入多个配置文件,可以在 <param-value>标记中用逗号作分隔符。
在web.xml里配置Listener
<listener>
<listener-class> org.springframework.web.context.ContextLoaderListener listener-class >
</listener>

参考:https://blog.csdn.net/zhangliao613/article/details/6289114

3、ContextLoaderListener
ContextLoaderListener是spring的核心监听器,它的作用是:在启动Web容器时,自动装配contextConfigLocation指定的xml配置信息。
因为它实现了ServletContextListener这个接口,在web.xml配置这个监听器,启动容器时,就会默认执行它实现的方法。在ContextLoaderListener中关联了ContextLoader这个类,所以整个加载配置过程由ContextLoader来完成。

参考并继续学习:https://blog.csdn.net/qq924862077/article/details/52769754
https://blog.csdn.net/MrZhangXL/article/details/78587426
https://www.cnblogs.com/hello-yao-ge/p/5891435.html
https://blog.csdn.net/liangxw1/article/details/51037533
https://www.cnblogs.com/quan-coder/p/8436471.html
https://www.cnblogs.com/Zyf2016/p/6374160.html

——————————
17.12.19

1、@Autowired与@Resource区别

前者属于基于类型装配。如果需要安装名称装配,需要配合使用@Autowired()@Qualifier("baseDao")

后者属于J2EE的注解。默认安照名称进行装配,名称可以通过name属性进行指定,如果没有指定name属性,当注解写在字段上时,默认取字段名进行按照名称查找,如果注解写在setter方法上默认取属性名进行装配。@Resource(name="baseDao")

再加一条:@Resource注解是由JDK提供,而@Autowired是由Spring提供。

java为我们提供了 javax.annotation.Resource这个注解。

spring框架提供了org.springframework.beans.factory.annotation.Autowired。

@Autowire 默认按照类型装配,默认情况下它要求依赖对象必须存在如果允许为null,可以设置它required属性为false,如果我们想使用按照名称装配,可 以结合@Qualifier注解一起使用;

@Resource默认按照名称装配,当找不到与名称匹配的bean才会按照类型装配,可以通过name属性指定,如果没有指定name属 性,当注解标注在字段上,即默认取字段的名称作为bean名称寻找依赖对象,当注解标注在属性的setter方法上,即默认取属性名作为bean名称寻找 依赖对象.

2、@Component,@Service,@Controller,@Repository的关系

答:在目前的 Spring 版本中,这 3 个注释和 @Component 是等效的。

但是从注释类的命名上,很容易看出这 3 个注解分别和持久层、业务层和控制层(Web 层)相对应。

也许 Spring 将在以后的版本中为这三个注解添加特殊的功能。

如果 Web 应用程序采用了经典的三层分层结构的话,最好在持久层、业务层和控制层分别采用 @Repository、@Service 和 @Controller对分层中的类进行注释

而用 @Component 对那些比较中立的类进行注释。

@Service: 为所有的web服务类型使用,所有业务逻辑都在这里 换句话说,数据相关的计算和 all.This 注释,我们的用户不直接调用持久化方法,因此它使用这个注释调用这个方法。 请求 @Repository 为每个用户请求
@Repository: 对所有存储的过程数据库连接使用,这是应用程序的数据访问层,用于从数据库获取数据。 换句话说,将所有相关的数据库操作都由仓库完成。
@Component - 用组件构造型注释其他组件的( 例如REST资源类) 。

3、@Configuration与@Component区别

答:(1)、@Component注解的范围最广,所有类都可以注解。但是@Configuration是一个配置类。

(2)、@Configuration是Spring2.5提供的注解,用于将所标注的类加载到 Spring 环境中,需要搭配 component-scan 使用。Configuration 是 Spring 3.X 后提供的注解,用于取代 XML 来配置 Spring。

(3)、在@Component类中使用方法或字段时不会使用CGLIB增强(及不使用代理类:调用任何方法,使用任何变量,拿到的是原始对象,后面会有例子解释)。而在@Configuration类中使用方法或字段时则使用CGLIB创造协作对象(及使用代理:拿到的是代理对象);当调用@Bean注解的方法时它不是普通的Java语义,而是从容器中拿到由Spring生命周期管理、被Spring代理甚至依赖于其他Bean的对象引用。在@Component中调用@Bean注解的方法和字段则是普通的Java语义,不经过CGLIB处理。

参考:http://blog.csdn.net/ttjxtjx/article/details/49866011

http://blog.csdn.net/isea533/article/details/78072133?locationNum=7&fps=1

4、注解分两类:一类用于将Bean装配。比如@Autowired,@Resource。

一类用于注册Bean,@Component , @Repository , @ Controller , @Service ,

@Configration这些注解都是把你要实例化的对象转化成一个Bean,放在IoC容器中,等你要用的时候,它会和上面的@Autowired ,

@Resource配合到一起,把对象、属性、方法完美组装。

参考:https://www.cnblogs.com/java-synchronized/p/6576507.html

5、@Bean 注解产生Bean的方法。因此@Bean都在方法上,说明该方法将产生一个Bean,然后交给Spring管理。

@Bean是一个方法级别上的注解,主要用在@Configuration注解的类里也可以用在@Component注解的类里

6、@Configration注解在类上。@Bean注解在方法上。怎么回事?

@Configration注解的类会被作为Bean交给Spring管理。
@Bean注解的方法会生成Bean交给Spring管理。他们两个是不矛盾的。
@Configuration可理解为用spring的时候xml里面的<beans>标签
@Bean可理解为用spring的时候xml里面的<bean>标签
参考:https://blog.csdn.net/u012260707/article/details/52021265

————————————

17.12.7

ICO很简单,写好类,在配置文件中写好<bean>,然后使用Java反射机制通过<bean>中的名字创建实例,然后注入到需要的实例中。

注解则是进一步对该过程进行封装,无需写配置文件,直接扫描注解进行如上步骤。

有时间来把两种方式的简单实现写一下。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,080评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,422评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,630评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,554评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,662评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,856评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,014评论 3 408
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,752评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,212评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,541评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,687评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,347评论 4 331
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,973评论 3 315
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,777评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,006评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,406评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,576评论 2 349

推荐阅读更多精彩内容