`
suhuanzheng7784877
  • 浏览: 708424 次
  • 性别: Icon_minigender_1
  • 来自: 北京
博客专栏
Ff8d036b-05a9-33b5-828a-2633bb68b7e6
读金庸故事,品程序人生
浏览量:47911
社区版块
存档分类
最新评论

Maven3实战笔记02坐标和依赖--1

阅读更多

1.  项目需求

加入我们现在有这样一个小小项目,就是做一个注册模块,让注册的人员记录可以插入到数据库中,还可以做账号的唯一性判断,注册成功后可以进行邮件提醒功能。书上功能很简单,其实重点不是功能,而是借由此示例说明Maven的特性。这一节咱们主要说明一下坐标与依赖的特性。其余的特性也皆由此案例中衍生出来。

2.  模块划分

基本模块功能分为

验证码生成:包括生成随即验证数字以及数字图片。

发送邮件:注册成功后需要给注册的Email发一封email,以便激活注册信息。

激活账户:用于邮件激活用户之后,用户才可用。

登录:一切成功后可以登录系统。

系统比较简单了,但是我们也分模块进行开发。也好体现Maven模块强解耦合的管理思想。

3.  邮件模块的实现

这里和书中的讲解顺序不太一样,我们先来开发功能模块,之后通过Maven的坐标和以来的概念来分析咱们的邮件模块。整个系统是B/S架构,采用Spring帮助我们进行类的管理。为了放大这个微型系统的规模,我们单独为这个邮件功能建立一个项目,模拟一个很大系统的一个模块。我们先看邮件模块的实现类吧,接口就不给出了

package com.liuyan.account.mail.impl;

import javax.mail.MessagingException;
import javax.mail.internet.MimeMessage;

import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.mail.javamail.MimeMessageHelper;

import com.liuyan.account.mail.AccountEmailService;

public class AccountEmailServiceImpl implements AccountEmailService {

	private JavaMailSender javaMailSender;

	public JavaMailSender getJavaMailSender() {
		return javaMailSender;
	}

	public void setJavaMailSender(JavaMailSender javaMailSender) {
		this.javaMailSender = javaMailSender;
	}

	private String systemEmail;

	public String getSystemEmail() {
		return systemEmail;
	}

	public void setSystemEmail(String systemEmail) {
		this.systemEmail = systemEmail;
	}

	@Override
	public void sendMail(String to, String subject, String message)
			throws MessagingException {

		MimeMessage msg = javaMailSender.createMimeMessage();
		MimeMessageHelper msgHelper = new MimeMessageHelper(msg);

		msgHelper.setFrom(systemEmail);
		msgHelper.setTo(to);
		msgHelper.setSubject(subject);
		msgHelper.setText(message);
		javaMailSender.send(msg);

	}

}

 之后在包/src/test/java编写测试用例

 

package com.liuyan.account.mail;

import javax.mail.MessagingException;

import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import com.icegreen.greenmail.util.GreenMail;
import com.icegreen.greenmail.util.ServerSetup;

public class AccountEmailServiceTest {

	private GreenMail greenMail;

	@Before
	public void startTest() {
		greenMail = new GreenMail(ServerSetup.SMTP);
		greenMail.setUser("suhuanzheng7784877@163.com", "1111");
		greenMail.start();
	}
	
	@Test
	public void sendMail() throws MessagingException {

		ApplicationContext ctx = new ClassPathXmlApplicationContext(
				"applicationContext.xml");

		AccountEmailService accountEmailService = (AccountEmailService) ctx
				.getBean("accountEmailService");

		String to = "suhuanzheng7784877@163.com";

		String subject = "测试";

		String message = "内容";

		accountEmailService.sendMail(to, subject, message);

	}

	@After
	public void stop() {
		greenMail.stop();
	}

}

 单元测试也写完了,之后就是项目构建、打包了。

在这之前我们来看看Spring配置文件的内容

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://www.springframework.org/schema/beans
	 http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
	 http://www.springframework.org/schema/aop
	 http://www.springframework.org/schema/aop/spring-aop-2.5.xsd"
	xmlns:aop="http://www.springframework.org/schema/aop" xmlns:p="http://www.springframework.org/schema/p">

	<!-- 加载Properties文件 -->
	<bean id="configurer"
		class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
		<property name="locations">
			<list>
				<value>classpath:mail.properties</value>
			</list>
		</property>
	</bean>

	<bean id="javaMailSender" class="org.springframework.mail.javamail.JavaMailSenderImpl">
		<property name="defaultEncoding" value="UTF-8" />
		<property name="host" value="${mail.host}" />
		<property name="username" value="${mail.username}" />
		<property name="password" value="${mail.password}" />
		<property name="javaMailProperties">
			<props>
				<!-- 设置认证开关 -->
				<prop key="mail.smtp.auth">true</prop>
				<!-- 启动调试开关 -->
				<prop key="mail.debug">true</prop>
			</props>
		</property>
	</bean>

	<bean id="accountEmailService" class="com.liuyan.account.mail.impl.AccountEmailServiceImpl">
		<property name="javaMailSender" ref="javaMailSender"></property>
		<property name="systemEmail" value="suhuanzheng7784877@163.com"></property>
	</bean>
</beans>

 mail.properties内容

mail.host=smtp.163.com
mail.username=suhuanzheng7784877@163.com
mail.password=111111
mail.from=suhuanzheng7784877@163.com
mail.to=suhuanzheng7784877@163.com

 下面就需要Maven出场了。

4.  Maven的介入

其实上面的程序打包已经按照了Maven的规约了~我们再来看看这个项目模块的代码结构

 

通过MyEclipse插件很快写出pom.xml文件内容

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
	<modelVersion>4.0.0</modelVersion>
	<groupId>com.liuyan.account</groupId>
	<artifactId>MavenAccount-email</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<dependencies>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-core</artifactId>
			<version>2.5.6</version>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-beans</artifactId>
			<version>2.5.6</version>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-context</artifactId>
			<version>2.5.6</version>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-context-support</artifactId>
			<version>2.5.6</version>
		</dependency>
		<dependency>
			<groupId>javax.mail</groupId>
			<artifactId>mail</artifactId>
			<version>1.4.1</version>
		</dependency>
		<dependency>
			<groupId>junit</groupId>
			<artifactId>junit</artifactId>
			<version>4.7</version>
			<scope>test</scope>
		</dependency>
		<dependency>
			<groupId>com.icegreen</groupId>
			<artifactId>greenmail</artifactId>
			<version>1.3.1b</version>
			<scope>test</scope>
		</dependency>
	</dependencies>

	<build>
		<resources>
			<resource>
				<directory>src/main/resource</directory>
			</resource>
		</resources>
	</build>
</project>

 

 运行一下命令。

mvn clean test

 自己的邮箱看看效果,多了一封邮件。Ok,再看本地仓库,唉~~~自己的c盘又添了不少东西。本地仓库会越来越大的。各位使用者要有心理准备,当然可以通过配置的方式转移本地仓库存储位置。

实际上是通过这个小例子说明坐标这个概念。在Maven中的坐标的意思就是各种构建引入的秩序,坐标是多维的。也就是groupIdartifactIdversionpackaging这几个元素决定了其组建的唯一标识(classifier没有看到,如果后面看到了再补充进来)。

前面也稍带提过了groupId是项目组的标识、artifactId是模块标识、version是版本号标识、packaging是打包方式,默认是jar方式。如此看来这些元素描述了一个不能重复的标识,groupId+ artifactId+ version+.+packaging在整个儿仓库中是不应该重复的。

	<groupId>com.liuyan.account</groupId>
	<artifactId>MavenAccount-email</artifactId>
	<version>0.0.1-SNAPSHOT</version>

 而其他项目需要你的模块为其服务的时候,也是根据坐标找到你的模块的。这就引出了下面依赖项的配置。这个模块依赖了Spring,不怕,我们从maven仓库中去取依赖就可以了,下面的问题就是:我们需要哪些依赖?这些依赖的版本是什么?

通过已有组件的坐标,我们可以轻易从Maven中心库中获取依赖包

		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-context-support</artifactId>
			<version>2.5.6</version>
		</dependency>

 描述我们这个邮件模块依赖org.springframework.spring-context-support.2.5.6.jar这个东东。果然,运行后在本地仓库中找到了

 

项目依赖可以有以下几种配置范围

1compile:默认值,这个代表在Maven项目周期的编译、测试、运行的3classpath都生效,也就是说Maven自己在项目不同生命周期使用的classpath不一样,一旦配置了compile,那么在以上三个周期会将依赖jar放到不同周期classpath中。

2test:测试期间有效,运行期间不必引入,就像junit包,在运行期间就没必要引入了。

3provided:在编译、测试期间有效,其余周期都没用到,比如servlet-api.jarweb容器提供了此规范apijar和实现。

4runtime:只在运行、测试期间生效,以JDKJDBC规范为代表,哦,还有JavaEEJPA规范。

5system:与本机系统环境绑定,在编译、测试期间有效,往往和本机环境绑定,移植性不太好。

依赖传播:单丝不成线,孤木不成林。一个项目需要依赖很多辅助包,我们的spring也不例外。下面是本项目的依赖关系图

 

咱们就拿spring-core来说事儿吧,本项目直接依赖于它,它呢也不是吃素的,也需要别人的支持,他需要apachecommons-logging。那么就导致了如果我们想要使用spring-core的功能,必须得引入这个commons-logging包喽。没有Maven之前,我们一般都是先引入我们直接需要的包,之后根据错误信息加上我们自身的开发经验一个一个去网上下载我们核心包需要的其他包。造成的结果是,花了大量的时间在网上找包,好不容易将项目run起来了,执行一个操作后,又发现在运行的时候还需要别的jar包,如此根据错误信息往复在网上找相关jar包。最后发现自己一个很简单的项目怎么引入了那么多的包啊!

使用Maven管理项目的话,它会自动为您找这种传递性的依赖,因为在Maven中心仓库的项目描述中都已经严格阐述了各个开源项目的依赖关系。诚然,这种传递性依赖也存在范围的问题。我们就拿上面的举例子,本发送邮件模块项目依赖于spring-core依赖范围是compile,而spring-core依赖于commons-logging也是compile范围。那么通过传递性,本项目对commons-logging的依赖也是compile。看下表

直接依赖范围

compile

test

provided

runtime

compile

compile

-

-

runtime

test

test

-

-

test

provided

provide

-

provided

provided

runtime

runtime

-

-

runtime

这个表是嘛意思呢?就是说一个项目的第一直接依赖假如是compile范围,那么它的第二依赖包如果也是compile,那么本项目和第二依赖包的依赖范围就是compile。如果一个项目的第一直接依赖假如是compile范围,那么它的第二依赖包如果是test,那么本项目和第二依赖包不存在任何依赖关系,也是,第一直接依赖包和第二依赖包是测试的时候才用到的。无需影响到其他使用者。

  • 大小: 39.7 KB
  • 大小: 73.8 KB
  • 大小: 91.8 KB
4
2
分享到:
评论
1 楼 viei 2011-11-17  
依赖关系图是自己画的还是工具生成的呢?

相关推荐

    Maven3实战笔记.pdf

    标题中提及的“Maven3实战笔记”指向了Maven这款流行的Java项目管理和自动化构建工具的第三个主要版本。Maven自从引入以来,就极大地简化了Java项目的构建过程,提高了项目构建的标准化程度。它使用项目对象模型...

    Maven3实战笔记(整合)

    **Maven3实战笔记(整合)** Maven3是一款强大的Java项目管理工具,它通过一套标准的构建生命周期和依赖管理机制,使得Java开发过程中的编译、测试、打包、部署等任务变得简单而高效。本笔记将深入探讨Maven3的安装、...

    maven学习笔记

    7. Maven实战 - 添加插件: - Compiler插件:用于编译源代码,可通过配置指定编译器版本,如`&lt;source&gt;1.6&lt;/source&gt;`和`&lt;target&gt;1.6&lt;/target&gt;`。 - Surefire插件:用于运行测试,可以配置忽略某些测试。 在实际...

    经典JavaEE5规范学习笔记

    - Maven学习笔记:介绍了Maven的实战应用,包括环境配置、坐标和依赖、仓库管理、生命周期和插件、聚合、继承、反应堆、Nexus使用、测试、Hudson集成、Profile定制、项目站点生成和插件编写等主题。 - 学习Maven的...

    Qt 采用http通信json解析读取天气

    Qt 采用http通信json解析读取天气

    岗位晋升360度调查表.doc

    岗位晋升360度调查表.doc

    合法辞退员工的N种方式.pptx

    合法辞退员工的N种方式.pptx

    大模型、Agent、具身智能及人形机器人学习全路径规划.pdf

    大模型、Agent、具身智能及人形机器人学习全路径规划.pdf

    华润万家员工手册.doc

    华润万家员工手册.doc

    招聘需求分析.xls

    招聘需求分析.xls

    光伏+蓄电池系统中双有源桥DC-DC变换器的Matlab仿真与MPPT及闭环控制实现

    内容概要:本文详细介绍了基于‘光伏(PV)+蓄电池+负载’架构的双有源桥DC-DC变换器仿真方法及其在Matlab 2021b中的具体实现。首先解析了光伏系统的MPPT控制,通过扰动观察法使光伏板始终处于最大功率点。接着讨论了蓄电池的恒流充放电控制,利用PI控制器确保电池的安全和高效运作。然后阐述了双有源桥DC-DC变换器的闭环控制机制,借助PID控制器维持系统输出电压的稳定性。最后,文章展示了如何在Matlab Simulink环境下构建完整的仿真模型,涵盖各模块间的电气连接与信号交互,为新能源系统的优化提供了理论和技术支持。 适合人群:从事电力电子、新能源系统设计的研究人员和工程师,尤其是那些需要深入了解光伏储能系统工作原理的人群。 使用场景及目标:适用于希望掌握光伏储能系统中关键组件如MPPT、恒流充放电控制及双有源桥DC-DC变换器的设计与仿真的技术人员。目标是在实际工程项目中提高系统的效率和可靠性。 其他说明:文中提供的代码片段和建模思路有助于读者更好地理解和实践相关技术,同时也强调了一些常见的陷阱和调试技巧,帮助避免潜在的问题。

    数学建模_Matlab_SPSS_教程分享_学习用途_1742838826.zip

    线性代数

    电机调速技术解析:直流电机双闭环与多种电机滞环调速方法对比

    内容概要:本文详细介绍了不同类型电机的调速方法,重点探讨了直流电机双闭环调速、永磁同步电机电流滞环闭环调速以及异步电机滞环电流调速。文中不仅提供了每种调速方法的基本原理和技术特点,还附带了相应的代码示例进行辅助解释。此外,文章对永磁同步电机的电流滞环调速与SVPWM调速进行了对比,指出了各自的优劣之处。最后,强调了在实际应用中选择合适调速方案的重要性。 适合人群:从事电机控制系统设计与开发的技术人员,尤其是有一定电机控制基础的研发人员。 使用场景及目标:适用于需要深入了解电机调速机制及其应用场景的专业人士。目标是帮助读者掌握不同电机调速方法的特点,以便在实际工程中做出最优选择。 其他说明:文章通过具体的代码实例展示了调速方法的实际应用,使读者能够更好地理解和实践相关技术。同时提醒读者在实际调试过程中要注意参数设置和硬件条件的影响。

    人员晋升推荐表.xls

    人员晋升推荐表.xls

    员工生日关怀方案.doc

    员工生日关怀方案

    模拟IC设计:解析国际知名大厂的SAR、Sigma-Delta和Pipeline ADC逆向工程

    内容概要:本文详细介绍了对国际知名大厂的三个逆向ADC电路(SAR ADC、Sigma-Delta ADC和Pipeline ADC)进行深入剖析。作者通过Cadence Virtuoso平台研究了这些电路的标准单元库设计,探讨了各个电路的关键技术和实现细节。对于24bit Sigma-Delta ADC,重点讨论了其调制器部分的时钟相位分配和噪声整形技术;对于16bit SAR ADC,则关注其比较器阵列的独特设计以及动态锁存比较器的应用;而对于14bit Pipeline ADC,着重分析了其级间放大器设计和电荷共享技术。此外,文中还提到了在将这些设计适配到自家工艺过程中遇到的问题及其解决方案,如电容寄生效应、时序约束调整、运放结构优化等。 适合人群:从事模拟集成电路设计的专业人士,尤其是对ADC设计感兴趣的工程师和技术研究人员。 使用场景及目标:帮助读者深入了解高精度ADC的工作原理和设计技巧,掌握逆向工程技术在实际项目中的应用,提高对不同工艺节点下ADC设计的理解和适应能力。 其他说明:文中提供了大量具体的代码片段和仿真命令,便于读者理解和实践。同时,作者分享了许多宝贵的经验教训,强调了在逆向工程中需要注意的技术细节和潜在风险。

    大型立体仓库智能物流系统的PLC控制与优化设计

    内容概要:本文详细介绍了大型立体仓库智能物流系统的构建与优化。该项目涉及一万多个库位、一百多台输送机和八台堆垛机,采用了西门子PLC作为控制核心,通过无线网桥与WCS和WMS系统对接。文章重点讲解了梯形图编程和功能块的应用,如输送机启停控制、堆垛机移动控制、路径规划、无线通讯处理以及异常处理机制。此外,还探讨了设备协同、逻辑优化、任务分配算法和速度曲线规划等方面的技术细节。 适合人群:从事工业自动化、智能仓储系统设计与开发的工程师和技术爱好者。 使用场景及目标:适用于智能仓储系统的设计、实施和维护,旨在提高系统的稳定性、效率和可维护性。 其他说明:文中提供了大量实际项目中的代码示例和调试经验,有助于读者理解和应用相关技术。

    新员工月工作总结表.xlsx

    新员工月工作总结表.xlsx

    西门子PLC汽车电子零件装配线SCL语言模块化编程与集成解决方案

    内容概要:本文详细介绍了基于西门子S7-1500 PLC的汽车电子零件装配线集成解决方案。主要内容涵盖伺服轴控制、阿特拉斯拧紧枪控制、康耐视视觉检测系统以及HMI界面的设计与实现。文中展示了如何利用SCL语言将多种工业设备(如HMI、伺服电机、六轴机器人等)的功能封装为标准化功能块,从而提高系统的模块化程度和可复用性。同时,还分享了一些实际项目中的调试经验和优化技巧,如通过调整加减速曲线避免机械振动、设置扭矩保持时间和视觉检测的防抖定时器等。 适合人群:从事自动化控制领域的工程师和技术人员,尤其是熟悉PLC编程和工业自动化设备集成的专业人士。 使用场景及目标:适用于汽车制造行业的生产线控制系统设计与实施。主要目标是帮助工程师快速掌握如何使用SCL语言构建高效稳定的PLC控制系统,提升生产效率和产品质量。 其他说明:文中不仅提供了详细的代码示例,还结合具体的应用场景进行了深入剖析,有助于读者更好地理解和应用相关技术。此外,强调了模块化编程的优势,如减少重复劳动、便于维护升级等。

    嵌入式系统中基于STM32/AT32/GD32的串口IAP Bootloader实现与远程升级方案

    内容概要:本文详细介绍了如何在STM32、AT32和GD32等Cortex-M系列MCU上实现串口IAP(In Application Programming)Bootloader,支持远程升级及RS485升级。主要内容涵盖Bootloader的工作原理、内存分配、通信协议设计、Flash写入操作以及跳转应用程序的关键步骤。文中提供了具体的代码示例,如Bootloader主循环、RS485收发控制、Flash写入、CRC校验等,并分享了多个实战经验和注意事项,确保数据传输的可靠性。 适合人群:从事嵌入式系统开发的技术人员,尤其是对STM32、AT32、GD32等国产MCU有一定了解并希望掌握串口IAP技术的研发人员。 使用场景及目标:适用于需要远程升级固件的嵌入式项目,帮助开发者避免现场升级带来的不便,提高设备维护效率。目标是让读者能够独立实现一个可靠的串口IAP Bootloader,掌握RS485通信和Flash编程的关键技术。 其他说明:文中提到的代码和配置已在GitHub上提供,方便读者下载和实践。同时,作者分享了许多实战经验和常见问题解决方案,有助于减少开发过程中可能出现的问题。

Global site tag (gtag.js) - Google Analytics