将scoped bean自动装入/注入控制器方法

时间:2013-04-23 06:59:31

标签: java spring spring-mvc spring-3 autowired

春天3.2。我做的每件事都有效:

@Controller
public class MyController {
    @Inject
    Provider<MyBean> provider;

    @RequestMapping("/chart")
    public void getChart(HttpServletResponse resp) {
        provider.get();
    }
}

但是当我将MyBean设置为getChart的参数时,它不起作用:

@Controller
public class MyController {

    @RequestMapping("/chart")
    public void getChart(HttpServletResponse resp, MyBean myBean) {
        // No such method MyBean.<init>()
    }
}

因此Spring尝试创建myBean的新实例,而不是使用已绑定的实例。

配置:

@Configuration
public class Config {
    @Inject
    @Bean @Scope("request")
    public MyBean provideMyBean(MyOtherBean myOtherBean) {
         return myOtherBean.getMyBean();
    }
}

如果我将控制器请求作为范围,它也不起作用,并将@Inject / @ Autowired添加到getChart()。然后它找不到HttpServletResponse实例(NoSuchBeanDefinitionException),尽管在请求范围内肯定必须有一个。

也许它只是在Spring中没有实现?

1 个答案:

答案 0 :(得分:1)

通过创建自定义HandlerMethodArgumentResolver解决:

/**
 * Resolves beans defined in {@link Config},
 * because Spring doesn't want to do it implicitly.
 *
 * Makes possible to write something like
 * @RequestMapping(value="/chart", method=RequestMethod.GET)
 * getChart(HttpServletRequest req, MyBean myBean)
 *
 * and Spring will inject both arguments.
 */
public class MethodArgumentResolver implements HandlerMethodArgumentResolver, BeanFactoryAware {
    private final Set<Class> knownTypes = Config.getDeclaredTypes();

    private BeanFactory beanFactory;

    @Override
    public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
        this.beanFactory = beanFactory;
    }

    @Override
    public boolean supportsParameter(MethodParameter parameter) {
        Class<?> type = parameter.getParameterType();
        return knownTypes.contains(type);
    }

    @Override
    public Object resolveArgument(
            MethodParameter parameter,
            ModelAndViewContainer mavContainer,
            NativeWebRequest webRequest,
            WebDataBinderFactory binderFactory) throws Exception {
        Class<?> type = parameter.getParameterType();
        return beanFactory.getBean(type);
    }
}

并在Config中:

static Set<Class> getDeclaredTypes() {
    Set<Class> result = Sets.newHashSet();
    Method[] methods = Config.class.getDeclaredMethods();
    for (Method method : methods) {
        if (method.getAnnotation(Bean.class) != null) {
            result.add(method.getReturnType());
        }
    }
    return result;
}