• springMVC拦截配置


    1、web.xml文件配置

    <!-- spring mvc -->
    <servlet>
    <servlet-name>DispatcherServlet</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <init-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>classpath*:spring-mvc.xml</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
    <servlet-name>DispatcherServlet</servlet-name>
    <url-pattern>*.rst</url-pattern>
    </servlet-mapping>

    contextConfigLocation

    在web.xml中通过contextConfigLocation配置spring,contextConfigLocation
    参数定义了要装入的 Spring 配置文件。

    2、spring-mvc文件

    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p" xmlns:context="http://www.springframework.org/schema/context"
    xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx" xmlns:mvc="http://www.springframework.org/schema/mvc"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
    http://www.springframework.org/schema/beans/spring-beans.xsd
    http://www.springframework.org/schema/context
    http://www.springframework.org/schema/context/spring-context-4.0.xsd
    http://www.springframework.org/schema/aop
    http://www.springframework.org/schema/aop/spring-aop-4.0.xsd
    http://www.springframework.org/schema/tx
    http://www.springframework.org/schema/tx/spring-tx-4.0.xsd
    http://www.springframework.org/schema/mvc
    http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd">

    <!--所要拦截的文件-->

    <context:component-scan base-package="com.sudytech.**.controller" />


    <mvc:annotation-driven>
    <mvc:message-converters register-defaults="true">
    <bean class="com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter">
    <property name="supportedMediaTypes">
    <list>
    <value>application/json;charset=UTF-8</value>
    <value>text/html;charset=UTF-8</value>
    </list>
    </property>
    </bean>
    </mvc:message-converters>
    </mvc:annotation-driven>

    <!-- 配置静态资源 -->
    <!-- <mvc:resources location="/upload/" mapping="/upload/**" /> -->

    <!-- 配置jsp页面解析器 -->
    <!-- <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver" p:prefix="/WEB-INF/view/" p:suffix=".jsp" p:order="0" /> -->

    <!-- 全局异常处理机制 <bean class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver"> <property name="exceptionMappings"> <props> <prop key="java.lang.RuntimeException">error</prop> <prop
    key="java.lang.Exception">error</prop> </props> </property> </bean> -->
    <!-- 权限拦截 -->
    <!-- <mvc:interceptors> -->
    <!-- <mvc:interceptor> -->
    <!-- <mvc:mapping path="/**" /> -->
    <!-- <bean class="com.***"></bean> -->
    <!-- </mvc:interceptor> -->
    <!-- </mvc:interceptors> -->

    <!-- 上传下载 -->
    <!-- <bean id="multipartResolver" -->
    <!-- class="org.springframework.web.multipart.commons.CommonsMultipartResolver"> -->
    <!-- <property name="maxUploadSize" value="104857600" /> -->
    <!-- <property name="maxInMemorySize" value="40960"></property> -->
    <!-- <property name="defaultEncoding" value="utf-8" /> -->
    <!-- </bean> -->

    </beans>

    3、context:component-scan

    默认情况下,<context:component-scan>查找使用构造型(stereotype)注解所标注的类,如@Component(组件),@Service(服务),@Controller(控制器),@Repository(数据仓库)

    我们具体看下<context:component-scan>的一些属性,以下是一个比较具体的<context:component-scan>配置

    复制代码
    <context:component-scan base-package="com.wjx.betalot" <!-- 扫描的基本包路径 -->
                            annotation-config="true" <!-- 是否激活属性注入注解 -->
                            name-generator="org.springframework.context.annotation.AnnotationBeanNameGenerator"  <!-- Bean的ID策略生成器 -->
                            resource-pattern="**/*.class" <!-- 对资源进行筛选的正则表达式,这边是个大的范畴,具体细分在include-filter与exclude-filter中进行 -->
                            scope-resolver="org.springframework.context.annotation.AnnotationScopeMetadataResolver" <!-- scope解析器 ,与scoped-proxy只能同时配置一个 -->
                            scoped-proxy="no" <!-- scope代理,与scope-resolver只能同时配置一个 -->
                            use-default-filters="false" <!-- 是否使用默认的过滤器,默认值true -->
                                      >
                <!-- 注意:若使用include-filter去定制扫描内容,要在use-default-filters="false"的情况下,不然会“失效”,被默认的过滤机制所覆盖 -->                   
                <!-- annotation是对注解进行扫描 -->
                <context:include-filter type="annotation" expression="org.springframework.stereotype.Component"/> 
                <!-- assignable是对类或接口进行扫描 -->
                <context:include-filter type="assignable" expression="com.wjx.betalot.performer.Performer"/>
                <context:include-filter type="assignable" expression="com.wjx.betalot.performer.impl.Sonnet"/>
                
                <!-- 注意:在use-default-filters="false"的情况下,exclude-filter是针对include-filter里的内容进行排除 -->
                <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
                <context:exclude-filter type="assignable" expression="com.wjx.betalot.performer.impl.RainPoem"/>
                <context:exclude-filter type="regex" expression=".service.*"/> 
    
    </context:component-scan>
    复制代码

    以上配置注释已经很详细了,当然因为这些注释,你若是想复制去验证,你得删掉注释。我们具体再说明一下这些注释:

    back-package:标识了<context:component-scan>元素所扫描的包,可以使用一些通配符进行配置

    annotation-config:<context:component-scan>元素也完成了<context:annotation-config>元素的工作,开关就是这个属性,false则关闭属性注入注解功能

    name-generator:这个属性指定你的构造型注解,注册为Bean的ID生成策略,这个生成器基于接口BeanNameGenerator实现generateBeanName方法,你可以自己写个类去自定义策略。这边,我们可不显示配置,它是默认使用org.springframework.context.annotation.AnnotationBeanNameGenerator生成器,也就是类名首字符小写的策略,如Performer类,它注册的Bean的ID为performer.并且可以自定义ID,如@Component("Joy").这边简单贴出这个默认生成器的实现。

    复制代码
    public String generateBeanName(BeanDefinition definition, BeanDefinitionRegistry registry) {
            if (definition instanceof AnnotatedBeanDefinition) {
                String beanName = determineBeanNameFromAnnotation((AnnotatedBeanDefinition) definition);
                if (StringUtils.hasText(beanName)) {
                    // Explicit bean name found.
                    return beanName;
                }
            }
            // Fallback: generate a unique default bean name.
            return buildDefaultBeanName(definition, registry);
    }
    复制代码

     Spring除了实现了AnnotationBeanNameGenerator生成器外,还有个org.springframework.beans.factory.support.DefaultBeanNameGenerator生成器,它为了防止Bean的ID重复,它的生成策略是类路径+分隔符+序号

     ,如com.wjx.betalot.performer.impl.Sonnet注册为Bean的ID是com.wjx.betalot.performer.impl.Sonnet#0,这个生成器不支持自定义ID,否则抛出异常。同样贴出代码,有兴趣的可以去看下。

    复制代码
    public static String generateBeanName(
                BeanDefinition definition, BeanDefinitionRegistry registry, boolean isInnerBean)
                throws BeanDefinitionStoreException {
    
            String generatedBeanName = definition.getBeanClassName();
            if (generatedBeanName == null) {
                if (definition.getParentName() != null) {
                    generatedBeanName = definition.getParentName() + "$child";
                }
                else if (definition.getFactoryBeanName() != null) {
                    generatedBeanName = definition.getFactoryBeanName() + "$created";
                }
            }
            if (!StringUtils.hasText(generatedBeanName)) {
                throw new BeanDefinitionStoreException("Unnamed bean definition specifies neither " +
                        "'class' nor 'parent' nor 'factory-bean' - can't generate bean name");
            }
    
            String id = generatedBeanName;
            if (isInnerBean) {
                // Inner bean: generate identity hashcode suffix.
                id = generatedBeanName + GENERATED_BEAN_NAME_SEPARATOR + ObjectUtils.getIdentityHexString(definition);
            }
            else {
                // Top-level bean: use plain class name.
                // Increase counter until the id is unique.
                int counter = -1;
                while (counter == -1 || registry.containsBeanDefinition(id)) {
                    counter++;
                    id = generatedBeanName + GENERATED_BEAN_NAME_SEPARATOR + counter;
                }
            }
            return id;
        }
    复制代码

    resource-pattern:对资源进行筛选的正则表达式,这边是个大的范畴,具体细分在include-filter与exclude-filter中进行。

    scoped-proxy: scope代理,有三个值选项,no(默认值),interfaces(接口代理),targetClass(类代理),那什么时候需要用到scope代理呢,举个例子,我们知道Bean的作用域scope有singleton,prototype,request,session,那有这么一种情况,当你把一个session或者request的Bean注入到singleton的Bean中时,因为singleton的Bean在容器启动时就会创建A,而session的Bean在用户访问时才会创建B,那么当A中要注入B时,有可能B还未创建,这个时候就会出问题,那么代理的时候来了,B如果是个接口,就用interfaces代理,是个类则用targetClass代理。这个例子出处:http://www.bubuko.com/infodetail-1434289.html。

    scope-resolver:这个属性跟name-generator有点类似,它是基于接口ScopeMetadataResolver的,实现resolveScopeMetadata方法,目的是为了将@Scope(value="",proxyMode=ScopedProxyMode.NO,scopeName="")的配置解析成为一个ScopeMetadata对象,Spring这里也提供了两个实现,我们一起看下。首先是org.springframework.context.annotation.AnnotationScopeMetadataResolver中,

    复制代码
    public ScopeMetadata resolveScopeMetadata(BeanDefinition definition) {
            ScopeMetadata metadata = new ScopeMetadata();
            if (definition instanceof AnnotatedBeanDefinition) {
                AnnotatedBeanDefinition annDef = (AnnotatedBeanDefinition) definition;
                AnnotationAttributes attributes = AnnotationConfigUtils.attributesFor(annDef.getMetadata(), this.scopeAnnotationType);
                if (attributes != null) {
                    metadata.setScopeName(attributes.getAliasedString("value", this.scopeAnnotationType, definition.getSource()));
                    ScopedProxyMode proxyMode = attributes.getEnum("proxyMode");
                    if (proxyMode == null || proxyMode == ScopedProxyMode.DEFAULT) {
                        proxyMode = this.defaultProxyMode;
                    }
                    metadata.setScopedProxyMode(proxyMode);
                }
            }
            return metadata;
        }
    复制代码

    对比一下org.springframework.context.annotation.Jsr330ScopeMetadataResolver中的实现:

    复制代码
    public ScopeMetadata resolveScopeMetadata(BeanDefinition definition) {
            ScopeMetadata metadata = new ScopeMetadata();
            metadata.setScopeName(BeanDefinition.SCOPE_PROTOTYPE);
            if (definition instanceof AnnotatedBeanDefinition) {
                AnnotatedBeanDefinition annDef = (AnnotatedBeanDefinition) definition;
                Set<String> annTypes = annDef.getMetadata().getAnnotationTypes();
                String found = null;
                for (String annType : annTypes) {
                    Set<String> metaAnns = annDef.getMetadata().getMetaAnnotationTypes(annType);
                    if (metaAnns.contains("javax.inject.Scope")) {
                        if (found != null) {
                            throw new IllegalStateException("Found ambiguous scope annotations on bean class [" +
                                    definition.getBeanClassName() + "]: " + found + ", " + annType);
                        }
                        found = annType;
                        String scopeName = resolveScopeName(annType);
                        if (scopeName == null) {
                            throw new IllegalStateException(
                                    "Unsupported scope annotation - not mapped onto Spring scope name: " + annType);
                        }
                        metadata.setScopeName(scopeName);
                    }
                }
            }
            return metadata;
        }
    复制代码

    ps:scope-resolver与scoped-proxy只能配置一个,配置了scope-resolver后你要使用代理,可以配置@Scope总的proxyMode属性项

    use-default-filters:是否使用默认的扫描过滤。

    <context:include-filter> :用来告知哪些类需要注册成Spring Bean,使用type和expression属性一起协作来定义组件扫描策略。type有以下5种

    过滤器类型 描述
    annotation 过滤器扫描使用注解所标注的那些类,通过expression属性指定要扫描的注释
    assignable 过滤器扫描派生于expression属性所指定类型的那些类
    aspectj 过滤器扫描与expression属性所指定的AspectJ表达式所匹配的那些类
    custom 使用自定义的org.springframework.core.type.TypeFliter实现类,该类由expression属性指定
    regex 过滤器扫描类的名称与expression属性所指定正则表示式所匹配的那些类

    要注意的是:若使用include-filter去定制扫描内容,要在use-default-filters="false"的情况下,不然会“失效”,被默认的过滤机制所覆盖

    <context:exclude-filter>:与<context:include-filter> 相反,用来告知哪些类不需要注册成Spring Bean,同样注意的是:在use-default-filters="false"的情况下,exclude-filter是针对include-filter里的内容进行排除。

  • 相关阅读:
    80年代的兄弟,你会什么?
    设计模式单件模式
    大冒险 这注定是部史诗级的探索。。。
    关于重构JS前端框架的失败经验(顺便怀念那些死去的代码)
    JDBC连接数据库类(主要用于存储过程)
    ActiveRecord学习(六):总结
    ASP.NET中常用的文件上传下载方法
    [整理]ASP.NET2.0新特性概述
    关于NHibernate中one to many 的问题
    关注06德国世界杯:比赛日程表
  • 原文地址:https://www.cnblogs.com/keyi/p/7521508.html
Copyright © 2020-2023  润新知