Package com.alibaba.citrus.springext.support.context

Source Code of com.alibaba.citrus.springext.support.context.InheritableBeanFactoryTests$RequestPostProcessor

/*
* Copyright (c) 2002-2012 Alibaba Group Holding Limited.
* All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
*    http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package com.alibaba.citrus.springext.support.context;

import static com.alibaba.citrus.test.TestEnvStatic.*;
import static com.alibaba.citrus.test.TestUtil.*;
import static org.easymock.EasyMock.*;
import static org.junit.Assert.*;

import java.io.File;
import java.lang.reflect.Proxy;
import javax.servlet.ServletContext;
import javax.servlet.ServletRequest;
import javax.servlet.http.HttpServletRequest;

import com.alibaba.citrus.springext.util.ProxyTargetFactory;
import com.meterware.servletunit.ServletRunner;
import org.junit.Test;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.core.io.ResourceLoader;

/**
* 确保singleton proxy可以工作。设计以下情形:
* <ul>
* <li>parent context中被置入了resolvableDependencies。</li>
* <li>this context中被置入了同名的dependencies。</li>
* <li>利用autowire注入对象,应该被注入parent中的对象。</li>
* </ul>
*
* @author Michael Zhou
*/
public class InheritableBeanFactoryTests {
    private XmlWebApplicationContext parentContext;
    private XmlWebApplicationContext thisContext;

    private void initContext(boolean withMockRequest) throws Exception {
        ServletContext servletContext = new ServletRunner(new File(srcdir, "WEB-INF/web.xml"), "").newClient()
                                                                                                  .newInvocation("http://localhost/servlet").getServlet().getServletConfig().getServletContext();

        // parent context,如果withMockRequest,则注册并覆盖原有的request
        parentContext = new XmlWebApplicationContext();
        parentContext.setConfigLocation(withMockRequest ? "beans-autowire-parent.xml" : "beans.xml");
        parentContext.setServletContext(servletContext);
        parentContext.refresh();

        // this context将会重新注册request,但是由于parent中已经注册了,不会被覆盖
        thisContext = new XmlWebApplicationContext();
        thisContext.setConfigLocation("beans-autowire.xml");
        thisContext.setServletContext(servletContext);
        thisContext.setParent(parentContext);
        thisContext.refresh();
    }

    /** 如果parent context中被置入mock request,那么取得并注入到autowire对象中。 */
    @Test
    public void request1() throws Exception {
        initContext(true);
        MyObject obj = (MyObject) thisContext.getBean("autowiredObject");
        assertEquals("mock_uri", obj.request.getRequestURI());
        assertSame(thisContext, obj.resourceLoader); // 确保非ProxyTargetFactory接口的对象不受影响
    }

    /** 如果parent context中没有置入mock request,那么autowire试图取得request失败。 */
    @Test
    public void request2() throws Exception {
        try {
            // 对于spring2,这一步就会抛出IllegalStateException: no thread-bound request found.
            initContext(false);

            // 对于spring3,会将request访问推迟到执行request方法时,才会抛出IllegalStateException: no thread-bound request found.
            // 这一点和request context的手法相同,但是由于request context采用了cglib,所以性能上更好一点。
            MyObject obj = (MyObject) thisContext.getBean("autowiredObject");
            assertTrue(Proxy.isProxyClass(obj.request.getClass()));
            assertSame(thisContext, obj.resourceLoader); // 确保非ProxyTargetFactory接口的对象不受影响

            obj.request.getRequestURI();
            fail();
        } catch (Exception e) {
            assertThat(e, exception(IllegalStateException.class, "No thread-bound request found"));
        }
    }

    public static class RequestPostProcessor implements BeanFactoryPostProcessor {
        public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
            HttpServletRequest mockRequest = createMock(RequestProxy.class);
            expect(mockRequest.getRequestURI()).andReturn("mock_uri").anyTimes();
            replay(mockRequest);

            beanFactory.registerResolvableDependency(ServletRequest.class, mockRequest);
        }
    }

    public static interface RequestProxy extends HttpServletRequest, ProxyTargetFactory {
    }

    public static class MyObject {
        @Autowired(required = false)
        private HttpServletRequest request;

        @Autowired
        private ResourceLoader resourceLoader;
    }
}
TOP

Related Classes of com.alibaba.citrus.springext.support.context.InheritableBeanFactoryTests$RequestPostProcessor

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.