Spring XML到Java配置:如何转换嵌套xml bean定义

vom3gejh  于 2022-11-21  发布在  Spring
关注(0)|答案(2)|浏览(150)
<bean
    name="ticketValidationFilter"
    class="org.jasig.cas.client.validation.Cas20ProxyReceivingTicketValidationFilter"
    p:service="https://my.local.service.com/cas-client">
    <property name="ticketValidator">
    <bean class="org.jasig.cas.client.validation.Cas20ServiceTicketValidator">
    <constructor-arg index="0" value="https://localhost:8443/cas" />
    </bean>
    </property>
  </bean>

有人能帮忙把这个xml定义转换成java配置吗?具体来说,我对如何声明ticketValidator感到困惑。

@Bean
    FilterRegistrationBean ticketValidationFilter(){

        Filter ticketValidationFilter = new
                org.jasig.cas.client.validation.Cas20ProxyReceivingTicketValidationFilter();

        FilterRegistrationBean frb = new FilterRegistrationBean();
        frb.addUrlPatterns("/*");
        frb.setFilter(ticketValidationFilter);

        // ticket Validator somewhere here

        Map<String, String> initParamMap = new HashMap<String, String>();
        initParamMap.put("service", "http://localhost:8889/cas-client");
        frb.setInitParameters(initParamMap);

        return frb;
    }

-----更新过滤器配置-------

如果你使用嵌套的bean来配置过滤器(比如我的例子),无论你在过滤器上设置了什么属性--如果你只使用setter,它们都将是null(不知道为什么,如果有人想解释的话,请解释)。
要解决此问题,请执行以下操作:创建一个扩展GenericFilterBean的过滤器(@Component)并在那里设置你的属性。然后将它 @autowired 到你的配置中并像往常一样在过滤器注册时使用setter。**
如果您有简单的配置属性(例如String),那么您可以使用带有init参数的Map,并在FilterRegistration bean上设置它。

5fjcxozz

5fjcxozz1#

由于它是一个仅在此特定外部bean中使用的bean,因此只需将其转换为示例创建并设置appropriate属性。
你不能使用Filter接口,因为它没有票验证器的设置器。
请改用AbstractTicketValidationFilter

@Bean
FilterRegistrationBean ticketValidationFilter(){

    AbstractTicketValidationFilter ticketValidationFilter = new
            org.jasig.cas.client.validation.Cas20ProxyReceivingTicketValidationFilter();

    FilterRegistrationBean frb = new FilterRegistrationBean();
    frb.addUrlPatterns("/*");
    frb.setFilter(ticketValidationFilter);

    //here be ticket validaror

    TicketValidator validator = new org.jasig.cas.client.validation.Cas20ServiceTicketValidator("https://localhost:8443/cas");

    ticketValidationFilter.setTicketValidator(validator);

    //end of ticket validator config

    Map<String, String> initParamMap = new HashMap<String, String>();
    initParamMap.put("service", "http://localhost:8889/cas-client");
    frb.setInitParameters(initParamMap);

    return frb;
}

java config的全部美妙之处在于,一些复杂的xml配置可以转换为非常简单的java。

xfb7svmp

xfb7svmp2#

根据org.springframework.context.ApplicationContextAware接口的Javadoc注解:
例如,当对象需要访问一组协作Bean时,实现此接口就很有意义。
@soulcheck的答案适用于大多数用例,但是当您出于任何原因需要向Spring注册内部bean时,比如定义init和destroy方法,您需要:
1.实施org.springframework.context.ApplicationContextAware
1.储存org.springframework.context.ApplicationContext,以便在@Bean方法内使用。
1.使用org.springframework.context.ApplicationContext访问org.springframework.beans.factory.support.BeanDefinitionRegistry,以手动创建和注册Bean定义。
1.再次使用org.springframework.context.ApplicationContext检索在上一步中创建的bean。
下面是一个类的示例框架,它显示了这些操作步骤:

import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class MyConfiguration implements ApplicationContextAware {
    // members ///////////////////////////////////////////////////////////////////////////
    private ApplicationContext applicationContext;

    // getters and setters ///////////////////////////////////////////////////////////////
    @Override
    public void setApplicationContext(final ApplicationContext applicationContext) {
        this.applicationContext = applicationContext;
    }

    // methods ///////////////////////////////////////////////////////////////////////////
    @Bean
    public Foo foo() {
        ((BeanDefinitionRegistry)applicationContext.getAutowireCapableBeanFactory()).registerBeanDefinition(
            "bar",
            BeanDefinitionBuilder.genericBeanDefinition(Bar.class)
                .setInitMethodName("start")
                .setDestroyMethodName("stop")
                .addConstructorArgValue("Hello world!")
                .addPropertyValue("hello", "world")
            .getBeanDefinition()
        );

        final Foo foo = new Foo(applicationContext.getBean("bar", Bar.class));

        return foo;
    }
}

相关问题