1. 程式人生 > >spring父子容器關係和@Value註解取不到值的問題

spring父子容器關係和@Value註解取不到值的問題

父子容器

  • Spring中可以包含多個容器,以SpringMVC為例, Spring為父容器SpringMVC為子容器
  • 父容器中的bean對子容器的bean是可見的,但是子容器的bean對父容器的bean是不可見的。
  • 父容器僅僅是 bean(物件) 對子容器可見,載入的全域性變數仍然相互獨立
  • 父子容器的關係類似於java的內部類。

@Value註解

  • Spring中的 @Value 註解可以獲得Spring容器中載入的全域性變數。以註解的形式賦予bean的成員變數。
@Value("${xxx}")
private String a;

@Value註解取不到值

環境

  • 一個mvc工程,配置檔案如下:
    1804.struct.png
  • spring-service.xml中載入屬性檔案,掃描service包中的bean。
  <!-- 載入配置檔案 -->
  <context:property-placeholder location="classpath:resource/*.properties"/>

  <!-- 掃描包載入Service實現類 -->
  <context:component-scan base-package="com.taotao.portal.service"/>
  • springmvc-config.xml中掃描controller,配置檢視解析器、攔截器。
  <context:component-scan base-package="com.taotao.portal.controller"/>
  <mvc:annotation-driven/>

  <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
    <property name="prefix" value="/WEB-INF/jsp/"/>
    <property name="suffix" value=".jsp"
/>
</bean> <!-- 攔截器配置 --> <mvc:interceptors> <mvc:interceptor> <!-- 攔截訂單類請求 --> <mvc:mapping path="/item/**"/> <bean class="com.taotao.portal.interceptor.LoginInterceptor"/> </mvc:interceptor> </mvc:interceptors>
  • web.xml中從spring-service.xml中載入bean到spring容器,從spring-config.xml中載入bean到springmvc容器,他們是父子關係。
  <!-- 載入spring容器 -->
  <context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>classpath:spring/spring-*.xml</param-value>
  </context-param>
  <listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
  </listener>

  <!-- springmvc的前端控制器 -->
  <servlet>
    <servlet-name>taotao-portal</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <init-param>
      <param-name>contextConfigLocation</param-name>
      <param-value>classpath:springmvc/springmvc-config.xml</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
  </servlet>
  <servlet-mapping>
    <servlet-name>taotao-portal</servlet-name>
    <!--偽靜態化,搜尋引擎優化-->
    <url-pattern>*.html</url-pattern>
  </servlet-mapping>
  • 攔截器實現類LoginInterceptor。自動組裝service類,使用Value註解獲取屬性檔案中定義的屬性。
public class LoginInterceptor implements HandlerInterceptor {

    private static final Logger LOGGER = LoggerFactory.getLogger(LoginInterceptor.class);

    @Autowired
    private UserService userService;

    @Value("${TT_TOKEN}")
    private String TT_TOKEN;
    @Value("${SSO_BASE_URL}")
    private String SSO_BASE_URL;
    @Value("${SSO_PAGE_LOGIN}")
    private String SSO_PAGE_LOGIN;


    /**
     * @return 是否放行
     */
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object o)
            throws Exception {
        //從cookie中取token,根據token取得使用者資訊
        String token = CookieUtils.getCookieValue(request, "TT_TOKEN");
        TbUser user = userService.getUser(token);

        //取不到使用者資訊
        if (user == null) {
            //跳轉到登入頁面,把使用者請求的url作為引數傳遞給登入頁面。
            String redirectUrl = SSO_BASE_URL + SSO_PAGE_LOGIN
                    + "?redirect=" + request.getRequestURL();
            LOGGER.debug("redirect: {}", redirectUrl);
            response.sendRedirect(redirectUrl);
            return false;
        }

        return true;

    }

    @Override
    public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o,
            ModelAndView modelAndView) throws Exception {
    }

    @Override
    public void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse,
            Object o, Exception e) throws Exception {
    }
}

現象

  • 訪問攔截器攔截的url:/item/**的時候,跳轉到預期之外的url,出現404。
  • 檢視日誌,發現容器將 @Value註解中的值賦予變數SSO_BASE_URL、SSO_PAGE_LOGIN,並沒有載入屬性檔案中的內容,從而未能實現應有的跳轉。
    1804.interceptvalue.png

原因

  • LoginInterceptor在spring-config.xml中配置,被載入到springMVC這一子容器中,屬性檔案的掃描在spring-service.xml中配置,被載入到spring這一父容器中。
  • 父容器中的bean(物件)對LoginInterceptor是可見的,但是父容器載入的屬性變數只是對父容器spring本身中的物件可見,所以LoginInterceptor使用 @Value註解無法在子容器springMVC中獲得對應的屬性值,只能取得容器賦予的預設值。

解決

再次載入

  • 在springMVC中再次掃描屬性檔案,載入到springMVC這一子容器中。
  <!-- 載入配置檔案 -->
  <context:property-placeholder location="classpath:resource/*.properties"/>

bean傳值

  • 在userService類中使用 @Value註解,載入spring的屬性。因為service類對於子容器可見,可以傳值。

相關推薦

spring父子容器關係@Value註解的問題

父子容器 Spring中可以包含多個容器,以SpringMVC為例, Spring為父容器 , SpringMVC為子容器 。 父容器中的bean對子容器的bean是可見的,但是子容器的b

關於spring value註解問題。

關於spring在service層  @value註解取不到值問題。 解決方法: 在applicationContext..xml 還有 applicationContext-mvc.xml 來年改革檔案,都加入 <context:property-placeholder lo

Spring:對@Autowired@Value註解的處理方法

在Spring中能夠完成依賴注入的註解有JavaSE提供的@Resource註解,就是上一篇文章介紹的。還有JavaEE提供的@javax.inject.Inject註解,這個用的很少,因為一般都不會去引用JavaEE的jar包。程式設計新說注:JavaEE早已經被Oracle拋棄了。JavaEE這個名字已經

SpringSpringMVC父子容器關係初探

一、背景   最近由於專案的包掃描出現了問題,在解決問題的過程中,偶然發現了Spring和SpringMVC是有父子容器關係的,而且正是因為這個才往往會出現包掃描的問題,我們在此來分析和理解Spring和SpringMVC的父子容器關係並且給出Spring和SpringMVC配

SpringSpringMVC父子容器關係初窺

一、背景   最近由於專案的包掃描出現了問題,在解決問題的過程中,偶然發現了Spring和SpringMVC是有父子容器關係的,而且正是因為這個才往往會出現包掃描的問題,我們在此來分析和理解Spring和SpringMVC的父子容器關係並且給出Spring和SpringMV

SpringSpringMVC父子容器關係

一、背景  最近由於專案的包掃描出現了問題,在解決問題的過程中,偶然發現了Spring和SpringMVC是有父子容器關係的,而且正是因為這個才往往會出現包掃描的問題,我們在此來分析和理解Spring和SpringMVC的父子容器關係並且給出Spring和SpringMVC配

spring與springMVC的細節問題:父子容器關係,載入controller,404錯誤

背景和概述 在spring與springMVC中通過IOC可以管理bean物件,有兩個配置檔案可以配置ioc spring的配置檔案applicationContext.xml springMVC的配置檔案springMVC.xml 工作中我們用spr

Spring、SpringMVC父子容器關係淺析

淺析配置檔案: web.xml ... <context-param> <param-name>contextConfigLocation</param-name> <para

這一次搞懂Spring Web零xml配置原理以及父子容器關係

# 前言 在使用Spring和SpringMVC的老版本進行開發時,我們需要配置很多的xml檔案,非常的繁瑣,總是讓使用者自行選擇配置也是非常不好的。基於**約定大於配置**的規定,Spring提供了很多註解幫助我們簡化了大量的xml配置;但是在使用SpringMVC時,我們還會使用到**WEB-INF/we

spring父子容器的問題

是把 ring ice ont con 資料 主動 spring 新建 這幾天做項目碰到一個問題,就是把配置文件中的參數往controller中註入的時候註入不進去,查了資料,發現是spring父子容器的原因, springmvc是spring的子容器,spring是父容器

spring父子容器

業務 不能訪問 mvc ioc 功能 擁有 特殊 arch 架構 通過HierarchicalBeanFactory接口,Spring的IoC容器可以建立父子層級關聯的容器體系,子容器可以訪問父容器中的Bean,但父容器不能訪問子容器的Bean。在容器內,Bean的id必須

關於 Spring 父子容器的三個問題

關於 Spring 父子容器的三個問題 前言   對 Spring 父容器和子容器做了一個案例的測試。對於已有的問題進行了一個好的測試。 正文   我先把本專案的Web啟動類,以及一些基本配置發上來。關於如何構建一個Web專案,可以引數我

Spring MVC 通過 @PropertySource@Value 來讀取配置檔案

Spring MVC 通過 @PropertySource和@Value 來讀取配置檔案 在這篇文章中,我們會利用Spring的@PropertySource和@Value兩個註解從配置檔案properties中讀取值。先來段java程式碼: @Component @PropertyS

Spring(七)用@Resource@Autowired註解完成屬性裝配及自動裝配

使用到註解需匯入jar包:common-annotations.jar 手工裝配依賴物件有兩種程式設計方式: 一、在xml配置檔案中通過bean節點進行配置,如: <?xml version="1.0" encoding="UTF-8"?>

理解spring父子容器

一、Spring和SpringMVC的父子容器關係 一般來說,我們在整合Spring和SpringMVC這兩個框架中,web.xml會這樣寫到: <!-- 載入spring容器 --> <!-- 初始化載入application.xml的各種配置檔案 --> <

spring 父子容器的概念,入門部落格推薦。必看

-------------------------------------------------20160519更新-----------------------------------------     1.1  ContextLoaderListener spr

純手寫Spring IoC容器之自定義註解實現

由於我在CSDN編輯器上寫這篇文章的時候,在貼上圖片上來的時候總是出現了卡頓,所以就另外寫了一個word文件裡面了,具體的實現過程請下載,裡面有文件、原始碼、資料庫sql檔案 連結:https://pan.baidu.com/s/1La2FIhlVKSt7JLh393V8I

通過Filter解決跨域問題,可以跨多個域,域可以通過@Value註解

跨域中不同的域指的是“協議+IP+埠”,只要其中一個不相同就要跨域訪問,為了安全,瀏覽器對於跨域預設是禁止訪問的。現在很多應用的客戶端和服務端是分開的,那麼如何來讓處於不同域的客戶端和服務端實現跨域訪問呢,而且客戶端還可能不止一個,那麼又如何實現多客戶端跨域訪問一個服務端

Spring問題集:@value放在Spring基於java的配置檔案中

在測試Spring的事務的時候需要連線資料庫,但是發現@Value的值一直就是“{${jdbc.url}}”,並沒有從配置檔案中獲取到值, 配置檔案的程式碼如下: @Configuration @ComponentScan(basePackages =

Spring:對@PostConstruct@PreDestroy註解的處理方法

在bean的例項化過程中,也會用到一系列的相關注解。如@PostConstruct和@PreDestroy用來標記初始化和銷燬方法。平常更多的是側重於應用,很少會有人去了解它背後發生的事情。今天就來看下它們的原始碼,這樣它們對你來說就不再是黑盒子了,而且學習原始碼對每個技術人來說都是必經之路。人們對事物的認知