Spring框架的隐藏功能?

时间:2009-09-12 23:21:11

标签: java spring

在看到许多关于编程语言的隐藏特性之后,我想知道Spring“事实上”框架的隐藏特性。如您所知,Spring文档隐藏了许多功能,并且很乐意分享它。

而你:你知道Spring框架的哪些隐藏功能?

6 个答案:

答案 0 :(得分:27)

Spring有一个强大的内置StringUtils

请注意以下数组包含一组id

String [] idArray = new String [] {"0", "1", "2", "0", "5", "2"} 

您想要删除重复的引用。就这么做吧

idArray = StringUtils.removeDuplicateStrings(idArray);

现在idArray将包含{“0”,“1”,“2”,“5”}。

还有更多。


是否可以使用Controller类而不在Web应用程序上下文文件中声明它们?

是的,只需将@Component放入其声明中(@Controller无法按预期工作)

package br.com.spring.view.controller

@Component
public class PlayerController extends MultiActionController {

    private Service service;

    @Autowired
    public PlayerController(InternalPathMethodNameResolver ipmnr, Service service) {
        this.service = service;

        setMethodNameResolver(ipmnr);
    }

    // mapped to /player/add
    public ModelAndView add(...) {}

    // mapped to /player/remove
    public ModelAndView remove(...) {}

    // mapped to /player/list
    public ModelAndView list(...) {}

}

因此在Web应用程序上下文文件中添加以下内容

<beans ...>
    <context:component-scan base-package="br.com.spring.view"/>
    <context:annotation-config/>
    <bean class="org.springframework.web.servlet.mvc.support.ControllerClassNameHandlerMapping">
        <property name="order" value="0"/>
        <property name="caseSensitive" value="true"/>
    </bean>
    <bean class="org.springframework.web.servlet.mvc.multiaction.InternalPathMethodNameResolver"/>
</beans>

没有别的


以动态形式验证?

使用以下

public class Team {

    private List<Player> playerList;    

}

所以在团队验证器中放

@Component
public class TeamValidator implements Validator {

    private PlayerValidator playerValidator;

    @Autowired
    public TeamValidator(PlayerValidator playerValidator) {
        this.playerValidator = playerValidator;
    }

    public boolean supports(Class clazz) {
        return clazz.isAssignableFrom(Team.class);
    }

    public void validate(Object command, Errors errors) {
        Team team = (Team) command;

        // do Team validation

        int index = 0;
        for(Player player: team.getPlayerList()) {
            // Notice code just bellow
            errors.pushNestedPath("playerList[" + index++ + "]");

            ValidationUtils.invokeValidator(playerValidator, player, errors);

            errors.popNestedPath();
        }

    }

}

网络表单中的继承?

使用ServlerRequestDataBinder以及隐藏的表单标志

public class Command {

    private Parent parent;

}

public class Child extends Parent { ... }

public class AnotherChild extends Parent { ... }

在您的控制器中执行以下操作

public class MyController extends MultiActionController {

    public ModelAndView action(HttpServletRequest request, HttpServletResponse response, Object command) {

        Command command = (Command) command;

        // hidden form flag
        String parentChildType = ServletRequestUtils.getRequiredStringParameter(request, "parentChildType");

        // getApplicationContext().getBean(parentChildType) retrieves a Parent object from a application context file
        ServletRequestDataBinder binder = 
            new ServletRequestDataBinder(getApplicationContext().getBean(parentChildType));

        // populates Parent child object
        binder.bind(request);

        command.setParent((Parent) binder.getTarget());
}

Spring有一个内置的扫描程序类ClassPathScanningCandidateComponentProvider。例如,您可以使用它来查找注释。

ClassPathScanningCandidateComponentProvider scanner =
    new ClassPathScanningCandidateComponentProvider(<DO_YOU_WANT_TO_USE_DEFAULT_FILTER>);

scanner.addIncludeFilter(new AnnotationTypeFilter(<TYPE_YOUR_ANNOTATION_HERE>.class));

for (BeanDefinition bd : scanner.findCandidateComponents(<TYPE_YOUR_BASE_PACKAGE_HERE>))
    System.out.println(bd.getBeanClassName());

Spring有一个有用的org.springframework.util.FileCopyUtils类。您可以使用

复制上传的文件
public ModelAndView action(...) throws Exception {

    Command command = (Command) command;

    MultiPartFile uploadedFile = command.getFile();

    FileCopyUtils.copy(uploadedFile.getBytes(), new File("destination"));

如果使用基于注释的控制器(Spring 2.5+)或普通MVC Spring控制器,则可以使用WebBindingInitializer注册全局属性编辑器。像

这样的东西
public class GlobalBindingInitializer implements WebBindingInitializer {

    public void initBinder(WebDataBinder binder, WebRequest request) {
        binder.registerCustomEditor(Date.class, new CustomDateEditor(new SimpleDateFormat("dd/MM/yyyy", true);
    }

}

因此,在您的Web应用程序上下文文件中,声明

<bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter">
    <property name="webBindingInitializer">
        <bean class="GlobalBindingInitializer"/>
    </property>
</bean>

这样任何基于注释的控制器都可以使用在GlobalBindingInitializer中声明的任何属性编辑器。

等等......

答案 1 :(得分:11)

Spring可以用作事件总线替换,因为ApplicationContext也是ApplicationEventPublisher

可以在SimpleApplicationEventMulticaster中找到引用Spring实现,它可以选择使用线程池异步分发事件。

答案 2 :(得分:1)

一个是使用基于CGLib的类代理来实现Spring的AOP。它也可以通过Java的动态代理来完成,但默认是CGLib。因此,如果您在堆栈跟踪中看到CGLib,请不要感到惊讶。

其他是使用AOP进行DI。是的,在你不知情的情况下,它到处都是AOP。很高兴知道你的代码是基于AOP的,即使你只是将Spring用于DI目的。

答案 3 :(得分:1)

热交换弹簧bean在运行时。

这对测试很有用。

请参阅here

答案 4 :(得分:0)

在Spring中查找任何隐藏功能的最佳方法是查看源代码。

很难说什么是隐藏功能,因为Spring对注释,AspectJ和DI的使用非常灵活。

答案 5 :(得分:0)

与典型的专有软件不同,Spring的源代码可供任何关心下载的人免费使用。

因此Spring没有隐藏的功能。它只是你还没见过的特色。