package extensiblexml.customtag;
import org.springframework.beans.factory.xml.NamespaceHandlerSupport;
public class MyNamespaceHandler extends NamespaceHandlerSupport {
public void init() {
registerBeanDefinitionParser("dateformat",
new SimpleDateFormatBeanDefinitionParser());
}
}
package extensiblexml.customtag;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.xml.AbstractSingleBeanDefinitionParser;
import org.springframework.util.StringUtils;
import org.w3c.dom.Element;
import java.text.SimpleDateFormat;
public class SimpleDateFormatBeanDefinitionParser extends AbstractSingleBeanDefinitionParser {
protected Class getBeanClass(Element element) {
return SimpleDateFormat.class;
}
@SuppressWarnings("deprecation")
protected void doParse(Element element, BeanDefinitionBuilder bean) {
// this will never be null since the schema explicitly requires that a value be supplied
String pattern = element.getAttribute("pattern");
bean.addConstructorArg(pattern);
// this however is an optional property
String lenient = element.getAttribute("lenient");
if (StringUtils.hasText(lenient)) {
bean.addPropertyValue("lenient", Boolean.valueOf(lenient));
}
}
}
@SuppressWarnings("unchecked")
List fileList = (List) context.getBean("xmlList");
for (File file : fileList) {
System.out.println(file.getName());
}
输出结果如下:
根据第一个例子中的步骤,各部分配置及代码如下:
core-commons-1.0.xsd:
CoreNamespaceHandler.java:
package extensiblexml.example;
import org.springframework.beans.factory.xml.NamespaceHandlerSupport;
public class CoreNamespaceHandler
extends NamespaceHandlerSupport
{
@Override
public void init() {
this.registerBeanDefinitionParser("fileList", new FileListDefinitionParser());
this.registerBeanDefinitionParser("fileFilter", new FileFilterDefinitionParser());
}
}
FileListDefinitionParser.java:
public class FileListDefinitionParser
extends AbstractSingleBeanDefinitionParser
{
/**
* The bean that is created for this tag element
*
* @param element The tag element
* @return A FileListFactoryBean
*/
@Override
protected Class> getBeanClass(Element element) {
return FileListFactoryBean.class;
}
/**
* Called when the fileList tag is to be parsed
*
* @param element The tag element
* @param ctx The context in which the parsing is occuring
* @param builder The bean definitions build to use
*/
@Override
protected void doParse(Element element, ParserContext ctx, BeanDefinitionBuilder builder) {
// Set the directory property
builder.addPropertyValue("directory", element.getAttribute("directory"));
// Set the scope
builder.setScope(element.getAttribute("scope"));
// We want any parsing to occur as a child of this tag so we need to make
// a new one that has this as it's owner/parent
ParserContext nestedCtx = new ParserContext(ctx.getReaderContext(), ctx.getDelegate(), builder.getBeanDefinition());
// Support for filters
Element exclusionElem = DomUtils.getChildElementByTagName(element, "fileFilter");
if (exclusionElem != null) {
// Just make a new Parser for each one and let the parser do the work
FileFilterDefinitionParser ff = new FileFilterDefinitionParser();
builder.addPropertyValue("filters", ff.parse(exclusionElem, nestedCtx));
}
// Support for nested fileList
List fileLists = DomUtils.getChildElementsByTagName(element, "fileList");
// Any objects that created will be placed in a ManagedList
// so Spring does the bulk of the resolution work for us
ManagedList
FileFilterDefinitionParser.java
public class FileFilterDefinitionParser
extends AbstractSingleBeanDefinitionParser
{
/**
* The bean that is created for this tag element
*
* @param element The tag element
* @return A FileFilterFactoryBean
*/
@Override
protected Class> getBeanClass(Element element) {
return FileFilterFactoryBean.class;
}
/**
* Called when the fileFilter tag is to be parsed
*
* @param element The tag element
* @param ctx The context in which the parsing is occuring
* @param builder The bean definitions build to use
*/
@Override
protected void doParse(Element element, ParserContext ctx, BeanDefinitionBuilder builder) {
// Set the scope
builder.setScope(element.getAttribute("scope"));
try {
// All of the filters will eventually end up in this list
// We use a 'ManagedList' and not a regular list because anything
// placed in a ManagedList object will support all of Springs
// functionalities and scopes for us, we dont' have to code anything
// in terms of reference lookups, EL, etc
ManagedList filters = new ManagedList();
// For each child node of the fileFilter tag, parse it and place it
// in the filtes list
NodeList nl = element.getChildNodes();
for (int i=0; i>
{
private final List filters = new ArrayList();
@Override
public Collection getObject() throws Exception {
return filters;
}
@Override
public Class> getObjectType() {
return Collection.class;
}
@Override
public boolean isSingleton() {
return false;
}
/**
* Go through the list of filters and convert the String ones
* (the ones that were set with and make them NameFileFilters
*/
public void setFilters(Collection filterList) {
for (Object o : filterList) {
if (o instanceof String) {
filters.add(new NameFileFilter(o.toString()));
}
else if (o instanceof FileFilter) {
filters.add((FileFilter)o);
}
}
}
}
}
DefinitionParserUtil.java:
package extensiblexml.example;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.config.BeanDefinitionHolder;
import org.springframework.beans.factory.support.BeanDefinitionReaderUtils;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.beans.factory.support.ManagedList;
import org.springframework.beans.factory.xml.BeanDefinitionParserDelegate;
import org.springframework.beans.factory.xml.ParserContext;
import org.springframework.expression.Expression;
import org.springframework.expression.ExpressionParser;
import org.springframework.expression.spel.standard.SpelExpressionParser;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
public class DefinitionParserUtil {
/**
* Parses the children of the passed in ParentNode for the following tags:
*
* value
* ref
* idref
* bean
* property
* *custom*
*
*
* The value tag works with Spring EL even in a Spring Batch scope="step"
*
* @param objects The list of resultings objects from the parsing (passed in for recursion purposes)
* @param parentNode The node who's children should be parsed
* @param ctx The ParserContext to use
* @param parentBean The BeanDefinition of the bean who is the parent of the parsed bean
* (i.e. the Bean that is the parentNode)
* @param scope The scope to execute in. Checked if 'step' to provide Spring EL
* support in a Spring Batch env
* @throws Exception
*/
public static void parseLimitedList(ManagedList objects, Node node,
ParserContext ctx, BeanDefinition parentBean, String scope)
throws Exception
{
parseLimitedList(objects, node, ctx, parentBean, scope, true);
}
/**
* Parses the children of the passed in ParentNode for the following tags:
*
* value
* ref
* idref
* bean
* property
* *custom*
*
*
* The value tag works with Spring EL even in a Spring Batch scope="step"
*
* @param objects The list of resultings objects from the parsing (passed in for recursion purposes)
* @param parentNode The node who's children should be parsed
* @param ctx The ParserContext to use
* @param parentBean The BeanDefinition of the bean who is the parent of the parsed bean
* (i.e. the Bean that is the parentNode)
* @param scope The scope to execute in. Checked if 'step' to provide Spring EL
* support in a Spring Batch env
* @param supportCustomTags Should we support custom tags within our tags?
* @throws Exception
*/
@SuppressWarnings("deprecation")
public static void parseLimitedList(ManagedList objects, Node node,
ParserContext ctx, BeanDefinition parentBean, String scope, boolean supportCustomTags)
throws Exception
{
// Only worry about element nodes
if (node.getNodeType() == Node.ELEMENT_NODE) {
Element elem = (Element)node;
String tagName = node.getLocalName();
if (tagName.equals("value")) {
String val = node.getTextContent();
// to get around an issue with Spring Batch not parsing Spring EL
// we will do it for them
if (scope.equals("step")
&& (val.startsWith("#{") && val.endsWith("}"))
&& (!val.startsWith("#{jobParameters"))
)
{
// Set up a new EL parser
ExpressionParser parser = new SpelExpressionParser();
// Parse the value
Expression exp = parser.parseExpression(val.substring(2, val.length()-1));
// Place the results in the list of created objects
objects.add(exp.getValue());
}
else {
// Otherwise, just treat it as a normal value tag
objects.add(val);
}
}
// Either of these is a just a lookup of an existing bean
else if (tagName.equals("ref") || tagName.equals("idref")) {
objects.add(ctx.getRegistry().getBeanDefinition(node.getTextContent()));
}
// We need to create the bean
else if (tagName.equals("bean")) {
// There is no quick little util I could find to create a bean
// on the fly programmatically in Spring and still support all
// Spring functionality so basically I mimic what Spring actually
// does but on a smaller scale. Everything Spring allows is
// still supported
// Create a factory to make the bean
DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();
// Set up a parser for the bean
BeanDefinitionParserDelegate pd = new BeanDefinitionParserDelegate(ctx.getReaderContext());
// Parse the bean get its information, now in a DefintionHolder
BeanDefinitionHolder bh = pd.parseBeanDefinitionElement(elem, parentBean);
// Register the bean will all the other beans Spring is aware of
BeanDefinitionReaderUtils.registerBeanDefinition(bh, beanFactory);
// Get the bean from the factory. This will allows Spring
// to do all its work (EL processing, scope, etc) and give us
// the actual bean itself
Object bean = beanFactory.getBean(bh.getBeanName());
objects.add(bean);
}
/*
* This is handled a bit differently in that it actually sets the property
* on the parent bean for us based on the property
*/
else if (tagName.equals("property")) {
BeanDefinitionParserDelegate pd = new BeanDefinitionParserDelegate(ctx.getReaderContext());
// This method actually set eh property on the parentBean for us so
// we don't have to add anything to the objects object
pd.parsePropertyElement(elem, parentBean);
}
else if (supportCustomTags) {
// handle custom tag
BeanDefinitionParserDelegate pd = new BeanDefinitionParserDelegate(ctx.getReaderContext());
BeanDefinition bd = pd.parseCustomElement(elem, parentBean);
objects.add(bd);
}
}
}
}
JSR-303是一个数据验证的规范,但是spring并没有对其进行实现,Hibernate Validator是实现了这一规范的,通过此这个实现来讲SpringMVC对JSR-303的支持。
JSR-303的校验是基于注解的,首先要把这些注解标记在需要验证的实体类的属性上或是其对应的get方法上。
登录需要验证类
public class Login {
@NotEmpty
引言:有时候需要在项目初始化的时候进行一系列工作,比如初始化一个线程池,初始化配置文件,初始化缓存等等,这时候就需要用到启动监听器,下面分别介绍一下两种常用的项目启动监听器
ServletContextListener
特点: 依赖于sevlet容器,需要配置web.xml
使用方法:
public class StartListener implements
The next group of methods has to do with rounding decimal values into integers. Three methods — Math.ceil(), Math.floor(), and Math.round() — handle rounding in differen