最近在工作中越来越经常的用到了Maven作为项目管理和Jar包管理和构建的工具,感觉Maven的确是很好用的。而且要将Maven的功能最大发挥出来,多模块是一个很好的集成例子。
一个Maven项目包括一个MavenProject和多个MavenModule
下面用一个标准的例子进行说明:
1.安装M2Eclipse插件。
1.点击Help-Market Place,查找Maven关键字
一直"下一步"不解释。接着就完成安装插件的动作了。
2.新建Parent项目,MavenProject,多图杀猫:
结果,在parent上运行会打出两个包,一个是jar包, 一个是war包,下面是结果日志:
一:知识点
在Spring IoC容器中配置Bean时,可能拥有一个以上的共享某些公用配置的Bean,比如属性和<bean>元素中的属性。你常常需要为多个Bean重复这些配置。
Spring允许你提取公用的Bean配置组成一个父Bean。从父Bean继承来的Bean称作子Bean。子Bean从父Bean继承Bean配置,包括Bean属性和<bean>元素中的属性,避免重复配置。子Bean在必要时也可以覆盖继承的配置。
父Bean可以作为配置模板,也可以同时作为Bean的一个实例。如果你希望父Bean只作为模板而不能检索,必须将abstract设置为true,要求Spring不要实例化这个Bean。
必须注意,并不是所有在父<bean>元素中定义的属性都将被继承。具体可参见Spring文档关于Bean继承的内容。
二、代码示例:
Bean配置文件:
<bean id="sequenceGenerator" class="com.jackie.codeproject.springrecipesnote.springioc.SequenceGenerator" > <property name="initial" value="100000" /> <property name="suffix" value="A" /> <property name="prefixGenerator" ref="datePrefixGenerator" /> </bean> <bean id="sequenceGenerator1" class="com.jackie.codeproject.springrecipesnote.springioc.SequenceGenerator" > <property name="initial" value="100000" /> <property name="suffix" value="A" /> <property name="prefixGenerator" ref="datePrefixGenerator" /> </bean> <bean id="datePrefixGenerator" class="com.jackie.codeproject.springrecipesnote.springioc.DatePrefixGenerator"> <property name="pattern" value="yyyyMMdd" /> </bean>为了避免重复相同的属性,可以用这些属性集声明一个基序列生成器。然后,两个序列生成器可以从这个基序列生成器中继承,这样它们自动拥有哪些属性集。如果子Bean和父Bean的class属性相同,就不需要指定。
<bean id="baseSequenceGenerator" class="com.jackie.codeproject.springrecipesnote.springioc.SequenceGenerator" > <property name="initial" value="100000" /> <property name="suffix" value="A" /> <property name="prefixGenerator" ref="datePrefixGenerator" /> </bean> <bean id="sequenceGenerator" parent="baseSequenceGenerator" /> <bean id="sequenceGenerator1" parent="baseSequenceGenerator" />继承的属性可以由子Bean覆盖。例如,可以添加不同初始值的子序列生成器。
<bean id="baseSequenceGenerator" class="com.jackie.codeproject.springrecipesnote.springioc.SequenceGenerator" > <property name="initial" value="100000" /> <property name="suffix" value="A" /> <property name="prefixGenerator" ref="datePrefixGenerator" /> </bean> <bean id="sequenceGenerator2" parent="baseSequenceGenerator" > <property name="initial" value="200000"></property> </bean>现在,基序列生成器Bean可以恢复为Bean实例使用。如果希望它仅作为模板,必须将abstract属性设置为true,则Spring不会实例化这个Bean,否则会抛异常。
<bean id="baseSequenceGenerator" abstract="true" class="com.jackie.codeproject.springrecipesnote.springioc.SequenceGenerator" > <property name="initial" value="100000" /> <property name="suffix" value="A" /> <property name="prefixGenerator" ref="datePrefixGenerator" /> </bean>你也可以忽略父Bean的类,让子Bean指定自己的类,特别是在父Bean与子Bean不在同一类层次结构但是共享同名属性的时候。在这种情况下,父Bean的abstract属性必须设置为true,因为父Bean不能实例化。例如,添加另一个也有initial属性的ReverseGenerator类。
public class ReverseGenerator { private int initial; public void setInitial(int initial) { this.initial = initial; } }现在,SequenceGenerator和ReverseGenerator不会扩展相同的基类,即他们不在相同的类层次机构中,但是具有同名的属性:initial。为了提取公共的initial属性,需要一个没有定义class属性的父Bean--------baseGenerator。
<bean id="baseGenerator" abstract="true"> <property name="initial" value="100000" /> </bean> <bean id="baseSequenceGenerator" abstract="true" parent="baseGenerator" > <property name="suffix" value="A" /> <property name="prefixGenerator" ref="datePrefixGenerator" /> </bean> <bean id="reverseGenerator" parent="baseGenerator" class="com.jackie.codeproject.springrecipesnote.springioc.ReverseGenerator" /> <bean id="sequenceGenerator" parent="baseSequenceGenerator" /> <bean id="sequenceGenerator1" parent="baseSequenceGenerator" /> <bean id="sequenceGenerator2" parent="baseSequenceGenerator" />
在Bean配置文件中设置autowire属性进行的自动装配将装配一个Bean的所有属性,不能仅仅装配特定的属性,这样不够灵活,而且只能通过类型或者名称自动装配Bean,如果这两种策略都不满足你的要求,就必须明确地装配Bean。
从Spring 2.5起,可以通过@Autowired或者@Resource(JSR-250规范定义的注解)注解一个设值方法、构造函数、字段甚至任意方法来自动装配特定的属性。须使用JDK5.0及以上版本。
为了要求Spring自动装配具有@Autowired或者@Resource注解的属性,你必须在IoC容器中注册一个AutowiredAnnotationBeanPostProcessor实例。如果你使用Bean工厂就必须通过API注册这个Bean后处理器,否则你只能在你的应用程序上下文里声明。
<bean class="org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor" />也可以简单地在Bean配置文件中包含<context:annotation-config />元素,这将自动注册一个AutowiredAnnotationBeanPostProcessor实例。
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd"> <context:annotation-config /> 。。。。。。。。。。。 </beans>(1)自动装配一个兼容类型的Bean
例如,可以用@Autowired注解prefixGenerator属性的设值方法。然后Spring将试图装配一个类型与prefixGenerator兼容的Bean。
/** * @param prefixGenerator * the prefixGenerator to set */ @Autowired public void setPrefixGenerator(PrefixGenerator prefixGenerator) { this.prefixGenerator = prefixGenerator; }如果IoC容器中定义了一个与PrefixGenerator类型兼容的Bean,将自动设置到prefixGenerator属性上。
<bean id="sequenceGenerator" class="com.jackie.codeproject.springrecipesnote.springioc.SequenceGenerator" > <property name="initial" value="100000" /> <property name="suffix" value="A" /> </bean> <bean id="datePrefixGenerator" class="com.jackie.codeproject.springrecipesnote.springioc.DatePrefixGenerator"> <property name="pattern" value="yyyyMMdd" /> </bean>默认情况下,所有带有@Autowired的属性都是必需的。当Spring不能找到匹配的Bean进行装配时,会抛出一个异常。比如将datePrefixGenerator这个Bean声明注掉,抛出:
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'sequenceGenerator': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire method: public void com.jackie.codeproject.springrecipesnote.springioc.SequenceGenerator.setPrefixGenerator(com.jackie.codeproject.springrecipesnote.springioc.PrefixGenerator); nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [com.jackie.codeproject.springrecipesnote.springioc.PrefixGenerator] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {}如果你希望某个属性是可选的,将@Autowired的required属性设置为false,这样当Spring找不到匹配的Bean就不设置该属性。
/** * @param prefixGenerator * the prefixGenerator to set */ @Autowired(required = false) public void setPrefixGenerator(PrefixGenerator prefixGenerator) { this.prefixGenerator = prefixGenerator; }除了设值方法,@Autowired注解还可以应用到构造函数,Spring将为每一个构造函数参数寻找一个具有兼容类型的Bean。
@Autowired public SequenceGenerator(PrefixGenerator prefixGenerator){ this.prefixGenerator = prefixGenerator; }@Autowired注解还可以应用到一个字段,即使这个字段没有声明为public。但用@Autowired注解非public的字段会降低代码的可测试性。
@Autowired private PrefixGenerator prefixGenerator;甚至可以将@Autowired注解应用到具有任意名称和任意数量参数的方法上,在这种情况下,Spring将试图为每个方法参数装配一个类型兼容的Bean。
@Autowired public void inject(PrefixGenerator prefixGenerator) { this.prefixGenerator = prefixGenerator; }(2)自动装配所有兼容类型的Bean
@Autowired注解还可以应用到一个数组类型的属性上,让Spring自动装配所有匹配的Bean。
@Autowired private PrefixGenerator[] prefixGenerator;如果IoC容器中有多个类型与PrefixGenerator兼容类型的Bean,它们将自动被添加到PrefixGenerator数组中。
<bean id="datePrefixGenerator" class="com.jackie.codeproject.springrecipesnote.springioc.DatePrefixGenerator"> <property name="pattern" value="yyyyMMdd" /> </bean> <bean id="yearPrefixGenerator" class="com.jackie.codeproject.springrecipesnote.springioc.YearPrefixGenerator"> <property name="pattern" value="yyyy" /> </bean>相似地,可以将@Autowired注解应用到类型安全的集合。Spring能够通过反射读取集合类型信息,自动装配所有类型兼容的Bean。
@Autowired private List<PrefixGenerator> prefixGeneratorList;如果Spring注意到@Autowired注解应用到了一个关键字为字符串的类型安全Map,它将在这个Map中添加所有Bean名称与关键字相同的兼容类型Bean。
@Autowired private Map<String, PrefixGenerator> prefixGenerators;(3)使用限定符的按类型自动装配
默认情况下,按照类型的自动装配在IoC容器中有超过一个类型兼容的Bean时无效。但Spring允许你指定一个候选Bean,这个Bean名称在@Qualifier注解中提供。
@Autowired @Qualifier("datePrefixGenerator") private PrefixGenerator prefixGenerator;Spring试图在IoC容器中查找一个具有这个名称的Bean,并将其装配到这个属性中。
@Qualifier注解也可以应用到方法参数中进行自动装配。
public void inject(@Qualifier("datePrefixGenerator") PrefixGenerator prefixGenerator) { this.prefixGenerator = prefixGenerator; }你也可以为自动装配创建一个自定义的限定符注解类型。这种注解类型必须用@Qualifier注解。
@Retention(RetentionPolicy.RUNTIME) @Target({ElementType.FIELD, ElementType.PARAMETER}) @Qualifier public @interface Generator { String value(); }然后,你可以将这个注解应用到@Autowired bean属性。这将要求Spring自动装配带有这个限定符注解和特定值的Bean。
@Autowired @Generator("prefix") p