使用@Configuration和@Controller注释一个类.需要帮助重构

Sam*_*Sam 10 java spring thymeleaf spring-boot

下面是我的类,我必须使用它们@Configuration,@Controller因为Thymeleaf在整个应用程序中应该只有一个实例,否则我会得到例外.我的其他类都带有注释,@RequestScope所以我不能使用单例作用域bean.所以我有一个配置和控制器的混合来获得结果,但我觉得这是一个不好的做法.我将不胜感激任何帮助重构代码并删除不良做法.

UPDATE

我在用spring-boot 1.5.14.我使用以下方法处理模板并将处理后的模板保持为字符串.

@Controller
@Configuration
@EnableWebMvc
@ApplicationScope
public class MyThymeleafConfig {

    @GetMapping("/view-template")
    @ResponseBody
    public void viewTemplates() {

        Context context = new Context();
        context.setVariable("mydata", "this is it");

        String html = templateEngine().process("templates/view-to-process.html", context);
        System.out.println(html);
    }


    /*

    configuration for thymeleaf and template processing

    */

    @Bean
    public SpringTemplateEngine templateEngine() {
        SpringTemplateEngine templateEngine = new SpringTemplateEngine();
        templateEngine.setTemplateResolver(thymeleafTemplateResolver());
        return templateEngine;
    }

    @Bean
    public SpringResourceTemplateResolver thymeleafTemplateResolver() {
        SpringResourceTemplateResolver templateResolver = new SpringResourceTemplateResolver();
        templateResolver.setPrefix("classpath:");
        templateResolver.setSuffix(".html");
        templateResolver.setCacheable(false);
        templateResolver.setTemplateMode(TemplateMode.HTML);
        return templateResolver;
    }

    @Bean
    public ThymeleafViewResolver thymeleafViewResolver() {
        ThymeleafViewResolver viewResolver = new ThymeleafViewResolver();
        viewResolver.setTemplateEngine(templateEngine());
        return viewResolver;
    }
}
Run Code Online (Sandbox Code Playgroud)

要为静态资源提供以下配置:

@Configuration
@EnableWebMvc
public class StaticResourceConfig implements WebMvcConfigurer {

    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        registry
                .addResourceHandler("/**")
                .addResourceLocations("/static/", "classpath:static/");
    }
}
Run Code Online (Sandbox Code Playgroud)

UPDATE

我还提到了为什么我不能接受下面提到的答案的原因,因为我的其他类有请求范围.

UPDATE

我有其他课程@RequestScope如下:

@RequestScope
@Controller
public class SecondController {

    @GetMapping("/viewPage")
    public String viewPage(Model model) {
        model.addAttribute("mydata", "sjfbsdf");
        model.addAttribute("somedata", "sjdfksfjhshgdfbskdfj");
        return "templates/view-to-process.html";
    }
}
Run Code Online (Sandbox Code Playgroud)

sed*_*ooe 7

假设您正在使用Spring Boot,因为您在标签中使用它,您不需要任何配置来使用Thymeleaf.

只需拥有此依赖关系,您就可以:

@GetMapping("/view-template")
public String viewTemplates(Model model) {
    model.addAttribute("mydata", "this is it")
    return "view-to-process";
}
Run Code Online (Sandbox Code Playgroud)

它应该工作.

顺便说一下,是的,拥有@Configuration@Controller在同一个班级是你永远不需要的东西.


NiV*_*VeR 7

如果您看到注释的源代码(Spring 5),您有:

调节器

@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Component
public @interface Controller {

    /**
     * The value may indicate a suggestion for a logical component name,
     * to be turned into a Spring bean in case of an autodetected component.
     * @return the suggested component name, if any (or empty String otherwise)
     */
    @AliasFor(annotation = Component.class)
    String value() default "";

}
Run Code Online (Sandbox Code Playgroud)

组态

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Component
public @interface Configuration {

    /**
     * Explicitly specify the name of the Spring bean definition associated
     * with this Configuration class. If left unspecified (the common case),
     * a bean name will be automatically generated.
     * <p>The custom name applies only if the Configuration class is picked up via
     * component scanning or supplied directly to a {@link AnnotationConfigApplicationContext}.
     * If the Configuration class is registered as a traditional XML bean definition,
     * the name/id of the bean element will take precedence.
     * @return the suggested component name, if any (or empty String otherwise)
     * @see org.springframework.beans.factory.support.DefaultBeanNameGenerator
     */
    @AliasFor(annotation = Component.class)
    String value() default "";
}
Run Code Online (Sandbox Code Playgroud)

你注意到它们是相同的(它们都包含更通用的@Component注释).所以通过看到这个事实来使用它们是没有意义的.另一件更重要的事情是,春天试图给出一种标签的意义,这些标签应该描述使用.

Configuration被用来在电线必要的零件给应用程序正常运行,在启动阶段.

Controller用于定义它作为向外界接口的类,即:如何其他演员使用你的应用.

正如您所看到的,将这两者结合使用毫无意义.


Mạn*_*yễn 6

要重构它们,将@Bean方法分离到单独的@Configuration类是容易和直接的:

@Configuration
// @Controller  is redundant as we have @Configuration
// @EnableWebMvc is also redundant since you already annotate it in other class
// @ApplicationScope is also redundant since you do not need to create bean of MyThymeleafConfig anymore
public class MyThymeleafConfig {
    /*

    configuration for thymeleaf and template processing

    */

    @Bean
    public SpringTemplateEngine templateEngine() {
        SpringTemplateEngine templateEngine = new SpringTemplateEngine();
        templateEngine.setTemplateResolver(thymeleafTemplateResolver());
        return templateEngine;
    }

    @Bean
    public SpringResourceTemplateResolver thymeleafTemplateResolver() {
        SpringResourceTemplateResolver templateResolver = new SpringResourceTemplateResolver();
        templateResolver.setPrefix("classpath:");
        templateResolver.setSuffix(".html");
        templateResolver.setCacheable(false);
        templateResolver.setTemplateMode(TemplateMode.HTML);
        return templateResolver;
    }

    @Bean
    public ThymeleafViewResolver thymeleafViewResolver() {
        ThymeleafViewResolver viewResolver = new ThymeleafViewResolver();
        viewResolver.setTemplateEngine(templateEngine());
        return viewResolver;
    }
}
Run Code Online (Sandbox Code Playgroud)

@Configuration class返回相同的bean实例,无论你调用bean方法多少次.

现在在您的控制器中:

@Controller
public class MyThymeleafConfig {

    @Autowired
    private SpringTemplateEngine templateEngine;

    @GetMapping("/view-template")
    @ResponseBody
    public void viewTemplates() {

        Context context = new Context();
        context.setVariable("mydata", "this is it");

        String html = templateEngine.process("templates/view-to-process.html", context);
        System.out.println(html);
    }
}
Run Code Online (Sandbox Code Playgroud)

但老实说,我不知道为什么你必须手动与TemplateEngine/SpringTemplateEngine交互,因为Spring-thymeleaf会自动为你提供给定变量的模板.(像@sedooe的例子)


tsa*_*txt 5

看一下Spring Boot文档的典型布局

另外这篇文章SOLID编程原理

看看Spring Boot指南Spring Boot Thymeleaf(你不需要你的@Bean配置)

用两个词来说,你应该将
1. MyThymeleafConfig配置
2. TemplateControllerviewTemplates()另一个端点分开


归档时间:

查看次数:

470 次

最近记录:

7 年,10 月 前