知识回顾
1、Maven可以帮助我们完成哪些工作?
答:构建项目、管理依赖、管理项目信息
2、如何通过Maven管理项目中的依赖类库?
答:在pom.xml中添加依赖类库的坐标
3、如何在IDEA中通过Maven构建一个web项目?
答:在IDEA中创建项目时选择“创建一个maven项目”,然后选择“从原型中创建”,在列表中选择org.apache.maven的webapp
知识目标
1、maven工程拆分与聚合思想【掌握】
2、maven子父工程【重点】
3、maven 私服【了解】
4、如何安装第三方jar包(安装到本地仓库和私服)【会用】
贯穿案例
使用Maven父子工程完成图书商城管理系统的项目构建
切片一、父子工程
1、为什么使用父子工程?
-痛点1:提高了代码的重用性
父控制器的存在就是为了去除重复,一个项目存在多个模块,可能由多个人开发,比如abc3个模块,3个模块都是基于spring的那么3个开发都需要引入spring的核心jar包,这样就引入了3份,但是使用父子工程,则只需要在父工程中引入了,则子工程自动继承。
-痛点2:提高了模块的分离度
按照以往的创建项目方式,一个maven项目就是一个大工程,一开始还能进行简单的测试编译,但是随着项目的不断变大和复杂化,后期再做改动则可能牵一发而动全身。但是使用父子工程,每个模块都是独立的,他们通过父控制器聚合在一起,这样当你要改动一个模块的时候你改动的也只是这一个模块而已,并不会影响其他的模块。
2、什么是父子工程?
父子工程说白了就是利用Maven的继承,依赖传递性来为我们省略一些重复的配置,通常配置在父模块中,为子模块提供使用,这样可以做到一处声明,处处使用。
继承
是为了消除重复,如果将dao、service、web分开创建独立的工程则每个工程的pom.xml文件中的内容存在重复,比如:设置编译版本、锁定spring的版本的等,可以将这些重复的配置提取出来在父工程的pom.xml中定义。
聚合
项目开发通常是分组分模块开发,每个模块开发完成要运行整个工程需要将每个模块聚合在一起运行,比如:dao、service、web三个工程最终会打一个独立的war运行。
3、如何使用父子工程?
项目需求:使用maven父子工程完成登录并跳转到首页列表
3.1、创建父子工程
3.1.1、创建父工程
提示:父工程只需要pom.xml文件,要将src目录删除。
#### 3.1.2、在父工程中以module的形式创建domain层子模块
因为domain层不需要页面所以创建控制台项目即可
注意:要在父工程上右键创建模块
#### 3.1.3、在父工程中以module的形式创建dao层子模块
因为dao层不需要页面所以创建控制台项目即可
注意:要在父工程上右键创建模块
#### 3.1.4、在父工程中以module形式创建service层子模块
因为service层不需要页面所以创建控制台项目即可
注意:要在父工程上右键创建模块
#### 3.1.5、在父工程中以module形式建web层子模块
注意:web层中包含controller和页面,所以web层要创建maven web工程
创建成功后,父工程的pom.xml中会自动引用所有的子模块
### 3.2、建立继承和依赖关系
在开发中,service要调用dao中的数据,而web又要调用service的数据,且domain又要被其他三层所调用,他们之间的调用关系如下:web->service->dao->domain
但是现在四个子工程相互是没有任何关系的,没有关系就不能调用。我们应该将他们之间关联起来
提示:maven项目之间的引用是通过本地仓库中的jar包进行引用,所以引用前要先将对应的模块打成jar包到本地仓库
3.2.1、配置domain模块的打包方式为jar
<packaging>jar</packaging>
#### 3.2.2、在dao子模块的pom中添加domain子模块的引用关系
#### 3.2.3、在service子模块的pom中添加dao子模块的引用关系
#### 3.2.4、在web子模块的pom中添加service子模块的引用关系
注意:web子模块的打包方式为war包
注意:在maven父子工程中父子工程不用直接建立关系,继承关系是先天的不用建立依赖关系。 平级之间的直接引用叫依赖,依赖不是先天的,需求要后天建立
3.3、在父工程的pom中添加ssm所需坐标
将项目所需的公共坐标添加到父工程的pom文件中
<?xml version="1.0" encoding="UTF-8"?>
<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/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>cn.woniu</groupId>
<artifactId>maven-parent</artifactId>
<version>1.0-SNAPSHOT</version>
<modules>
<module>maven-domain</module>
<module>maven-dao</module>
<module>maven-service</module>
<module>maven-web</module>
</modules>
<packaging>pom</packaging>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
<spring.version>5.3.6</spring.version>
</properties>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
<!--spring-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${spring.version}</version>
</dependency>
<!--aop坐标-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aspects</artifactId>
<version>${spring.version}</version>
</dependency>
<!--spring测试-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>${spring.version}</version>
</dependency>
<!--cglib-->
<dependency>
<groupId>cglib</groupId>
<artifactId>cglib</artifactId>
<version>3.3.0</version>
</dependency>
<!--spring事务坐标-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.20</version>
</dependency>
</dependencies>
<build>
<!--解决maven项目不加载静态资源文件-->
<resources>
<resource>
<directory>${basedir}/src/main/java</directory>
<includes>
<include>**/*.xml</include>
<include>**/*.properties</include>
</includes>
</resource>
<resource>
<directory>${basedir}/src/main/resources</directory>
<includes>
<include>**/*.xml</include>
<include>**/*.properties</include>
</includes>
</resource>
</resources>
</build>
</project>
3.4、编写domain子模块代码
创建实体类,注意实体类要实现序列化接口Serializable
package cn.woniu.domain;
import java.io.Serializable;
import java.math.BigDecimal;
/**
* 用户实体类
*/
public class User implements Serializable {
private int id;
private String userName;
private String passwd;
//省略Getter和Setter
实体类编写完成后,由于需要被 其他模块引用所以要将实体类发布到本地仓库中
打包完成后本地仓库的cn/woniu目录下就会生成一个maven-domain.jar
3.5、编写dao子模块代码
3.5.1、配置MyBatis相关坐标
<?xml version="1.0" encoding="UTF-8"?>
<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/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>maven-parent</artifactId>
<groupId>cn.woniu</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<packaging>jar</packaging>
<modelVersion>4.0.0</modelVersion>
<artifactId>maven-dao</artifactId>
<dependencies>
<!--依赖domain模块-->
<dependency>
<groupId>cn.woniu</groupId>
<artifactId>maven-domain</artifactId>
<version>1.0-SNAPSHOT</version>
<scope>compile</scope>
</dependency>
<!--logback日志相关-->
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.2.7</version>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-core</artifactId>
<version>1.2.7</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.32</version>
</dependency>
<!--mybaits-->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.7</version>
</dependency>
<!--数据库驱动-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.27</version>
</dependency>
<!--mybatis-dynamic坐标-->
<dependency>
<groupId>org.mybatis.dynamic-sql</groupId>
<artifactId>mybatis-dynamic-sql</artifactId>
<version>1.2.1</version>
</dependency>
<!--druid数据源-->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.2.5</version>
</dependency>
<!--spring操作jdbc坐标-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>5.3.6</version>
</dependency>
<!--spring整合mybaits坐标-->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<version>2.0.6</version>
</dependency>
<!--分页插件-->
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper</artifactId>
<version>5.2.1</version>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.12</version>
</dependency>
</dependencies>
<build>
<plugins>
<!--mybatis generator自动生成配置-->
<plugin>
<groupId>org.mybatis.generator</groupId>
<artifactId>mybatis-generator-maven-plugin</artifactId>
<version>1.4.0</version> <!-- 不要低于 1.4.0 版本 -->
<dependencies>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.27</version>
</dependency>
<dependency>
<groupId>org.mybatis.generator</groupId>
<artifactId>mybatis-generator-core</artifactId>
<version>1.4.0</version> <!-- 不要低于 1.4.0 版本 -->
</dependency>
</dependencies>
<configuration>
<verbose>true</verbose> <!-- 允许移动生成的文件 -->
<overwrite>true</overwrite> <!-- 是否覆盖 -->
<!--配置文件的路径 -->
<configurationFile>src/main/resources/mybatis-generator-config.xml</configurationFile>
</configuration>
</plugin>
</plugins>
</build>
</project>
3.5.1、配置数据库连接信息
在resources文件夹下添加数据源配置文件db.properties
jdbc.driverClassName=com.mysql.cj.jdbc.Driver
jdbc.url=jdbc:mysql://127.0.0.1:3306/test_mybatis?serverTimezone=GMT%2B8&useUnicode=true&characterEncoding=utf-8&useSSL=false
jdbc.username=root
jdbc.password=Aa123123.
在cn.woniu.config包中创建数据源配置类DataBaseConfig
package cn.woniu.config;
import com.alibaba.druid.pool.DruidDataSource;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.PropertySource;
/**
* 数据源配置类
*/
@PropertySource(value={"classpath:db.properties"})//读取properties文件
public class DataBaseConfig {
@Value("${jdbc.driverClassName}")
private String driverClassName;
@Value("${jdbc.url}")
private String url;
@Value("${jdbc.username}")
private String userName;
@Value("${jdbc.password}")
private String password;
/**
* 配置数据源
* @return
*/
@Bean(name="dataSource",initMethod = "init", destroyMethod = "close")
public DruidDataSource createDataSource(){
DruidDataSource dataSource = new DruidDataSource();
dataSource.setUsername(userName);
dataSource.setPassword(password);
dataSource.setUrl(url);
dataSource.setDriverClassName(driverClassName);
return dataSource;
}
}
3.5.2、创建SpringDaoConfig配置类
在cn.woniu.config包中创建dao层的Spring配置类SpringDaoConfig
package cn.woniu.config;
import com.github.pagehelper.PageInterceptor;
import org.apache.ibatis.plugin.Interceptor;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.mapper.MapperScannerConfigurer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import javax.sql.DataSource;
import java.util.Properties;
/**
* dao层spring配置类
*/
@Configuration
@ComponentScan(basePackages = {"cn.woniu.dao"})
@Import(value={DataBaseConfig.class})
public class SpringDaoConfig {
/**
* 创建SqlSessionFactory工厂
* @return
*/
@Bean
public SqlSessionFactoryBean sqlsessionfactoryBean(DataSource dataSource){
SqlSessionFactoryBean sqlSessionFactoryBean=new SqlSessionFactoryBean();
//为数据源赋值
sqlSessionFactoryBean.setDataSource(dataSource);
//设置分页拦截器
PageInterceptor pageInterceptor=new PageInterceptor();
//创建PageHelper插件需要的参数集合
Properties properties=new Properties();
//配置数据库方言为 mysql
properties.setProperty("helperDialect","mysql");
//配置分页的合理化数据
properties.setProperty("reasonable","true");
pageInterceptor.setProperties(properties);
//将分页拦截器添加到SqlSessionFactoryBean
sqlSessionFactoryBean.setPlugins(new Interceptor[]{pageInterceptor});
return sqlSessionFactoryBean;
}
/**
* 配置mybaits的dao包扫描
* @return
*/
@Bean
public MapperScannerConfigurer mapperScannerConfigurer(){
MapperScannerConfigurer mapperScanner=new MapperScannerConfigurer();
mapperScanner.setBasePackage("cn.woniu.dao");
return mapperScanner;
}
}
3.5.3、编写业务代码
在cn.woniu.dao包下创建UserMapper
package cn.woniu.dao;
import cn.woniu.domain.User;
import org.springframework.stereotype.Repository;
import java.util.List;
@Repository
public interface UserMapper {
List<User> selectAll();
}
在resources/cn/woniu/dao下创建UserMapper.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="cn.woniu.dao.UserMapper">
<resultMap id="userResult" type="cn.woniu.domain.User">
<result column="user_name" property="userName"></result>
<result column="passwd" property="passwd"></result>
</resultMap>
<select id="selectAll" resultMap="userResult">
select * from t_user
</select>
</mapper>
3.6、编写service子模块代码
3.6.1、在service的pom.xml中添加dao模块的依赖
<dependencies>
<!--依赖dao模块-->
<dependency>
<groupId>cn.woniu</groupId>
<artifactId>maven-dao</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
</dependencies>
提示:service层中的spring配置文件只配置事务相关的配置,注意配置文件的名称
在cn.woniu.config包中创建SpringServiceConfig配置
package cn.woniu.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.transaction.annotation.EnableTransactionManagement;
import javax.sql.DataSource;
/**
* service层spring配置类
*/
@Configuration
@ComponentScan(basePackages = {"cn.woniu.service.impl"})
@EnableAspectJAutoProxy(proxyTargetClass = true) //开启aop
@EnableTransactionManagement //开启事务
public class SpringServiceConfig {
/**
* 配置事务管理器
* @return
*/
@Bean
public DataSourceTransactionManager transactionManager(DataSource dataSource){
DataSourceTransactionManager transactionManager=new DataSourceTransactionManager();
transactionManager.setDataSource(dataSource);
return transactionManager;
}
}
3.6.2、编写业务代码
在cn.woniu.service包下创建IUserService
package cn.woniu.service;
import cn.woniu.domain.User;
import java.util.List;
public interface IUserService {
List<User> getAll();
}
在cn.woniu.service.impl包下创建实现类UserServiceImpl
package cn.woniu.service.impl;
import cn.woniu.dao.UserMapper;
import cn.woniu.domain.User;
import cn.woniu.service.IUserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
@Service
public class UserServiceImpl implements IUserService {
@Autowired
private UserMapper userMapper;
@Override
public List<User> getAll() {
return userMapper.selectAll();
}
}
3.7、编写web子模块
3.7.1、配置pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<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/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>maven-parent</artifactId>
<groupId>cn.woniu</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>maven-web</artifactId>
<!--web模块的打包方式为war-->
<packaging>war</packaging>
<name>maven-web Maven Webapp</name>
<!-- FIXME change it to the project's website -->
<url>http://www.example.com</url>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
</properties>
<dependencies>
<!--依赖service模块-->
<dependency>
<groupId>cn.woniu</groupId>
<artifactId>maven-service</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<!--spring web支持坐标-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>5.3.6</version>
</dependency>
<!--springmvc坐标-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.3.6</version>
</dependency>
<!--servlet坐标-->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<version>2.5</version>
<scope>provided</scope>
</dependency>
<!--jsp api坐标-->
<dependency>
<groupId>javax.servlet.jsp</groupId>
<artifactId>jsp-api</artifactId>
<version>2.0</version>
<scope>provided</scope>
</dependency>
<!--jstl相关坐标-->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
</dependency>
<dependency>
<groupId>taglibs</groupId>
<artifactId>standard</artifactId>
<version>1.1.2</version>
</dependency>
<!--springmvc 需要的json相关坐标-->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.9.0</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>2.9.0</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
<version>2.9.0</version>
</dependency>
<!--文件上传所需坐标-->
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.4</version>
</dependency>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.10.0</version>
</dependency>
</dependencies>
<build>
<finalName>maven-web</finalName>
<pluginManagement><!-- lock down plugins versions to avoid using Maven defaults (may be moved to parent pom) -->
<plugins>
<plugin>
<artifactId>maven-clean-plugin</artifactId>
<version>3.1.0</version>
</plugin>
<!-- see http://maven.apache.org/ref/current/maven-core/default-bindings.html#Plugin_bindings_for_war_packaging -->
<plugin>
<artifactId>maven-resources-plugin</artifactId>
<version>3.0.2</version>
</plugin>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.0</version>
</plugin>
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.22.1</version>
</plugin>
<plugin>
<artifactId>maven-war-plugin</artifactId>
<version>3.2.2</version>
</plugin>
<plugin>
<artifactId>maven-install-plugin</artifactId>
<version>2.5.2</version>
</plugin>
<plugin>
<artifactId>maven-deploy-plugin</artifactId>
<version>2.8.2</version>
</plugin>
</plugins>
</pluginManagement>
</build>
</project>
3.7.2、创建SpringMVC配置类
在cn.woniu.config包下创建WebMvcConfig
package cn.woniu.config;
import cn.woniu.converter.DateConverter;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.format.FormatterRegistry;
import org.springframework.web.multipart.MultipartResolver;
import org.springframework.web.multipart.commons.CommonsMultipartResolver;
import org.springframework.web.servlet.config.annotation.DefaultServletHandlerConfigurer;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import org.springframework.web.servlet.view.InternalResourceViewResolver;
/**
* SpringMvc配置类
*/
@Configuration
@EnableWebMvc //开启springmvc支持
@ComponentScan(basePackages = {"cn.woniu.controller","cn.woniu.exception"}) //扫描controller中的springmvc注解
public class WebMvcConfig implements WebMvcConfigurer {
/**
* 配置视图解析器
* @return
*/
@Bean
public InternalResourceViewResolver viewResolver(){
InternalResourceViewResolver viewResolver=new InternalResourceViewResolver();
//配置前缀
viewResolver.setPrefix("/WEB-INF/view/");
viewResolver.setSuffix(".jsp");
return viewResolver;
}
/**
* 配置springmvc忽略webapp下的所有静态资源
* @param configurer
*/
@Override
public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
configurer.enable();
}
/**
* 注册自定义类型转换器
* @param registry
*/
@Override
public void addFormatters(FormatterRegistry registry) {
registry.addConverter(new DateConverter());
}
/**
* 配置文件解析器
* @return
*/
@Bean
public MultipartResolver multipartResolver() {
CommonsMultipartResolver resolver = new CommonsMultipartResolver();
//设置上传文件的大小
resolver.setMaxUploadSize(10485760);
return resolver;
}
}
3.7.3、创建Spring配置文件读取类
package cn.woniu.config;
import org.springframework.web.filter.CharacterEncodingFilter;
import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer;
import javax.servlet.Filter;
/**
* WEB项目的启动类(spring+springmvc环境)
*/
public class WebInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {
/**
* 读取spring核心配置类
* @return
*/
@Override
protected Class<?>[] getRootConfigClasses() {
return new Class[]{
SpringDaoConfig.class,
SpringServiceConfig.class
};
}
/**
* 读取springmvc的配置类
* @return
*/
@Override
protected Class<?>[] getServletConfigClasses() {
return new Class[]{
WebMvcConfig.class//读取springMVC核心配置类
};
}
/**
* 配置springmvc对url中的哪些请求进行拦截处理
* @return
*/
@Override
protected String[] getServletMappings() {
return new String[]{"/"};
}
/**
* 设置springmvc中文乱码过滤器
* @return
*/
@Override
protected Filter[] getServletFilters() {
Filter encodingFilter = new CharacterEncodingFilter("UTF-8", true);
return new Filter[]{encodingFilter};
}
}
3.7.4、创建业务类
在cn.woniu.controller包下创建TestController
package cn.woniu.controller;
import cn.woniu.domain.User;
import cn.woniu.service.IUserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
@RestController
public class TestController {
@Autowired
private IUserService userService;
@RequestMapping("/t1")
public List<User> test1(){
return userService.getAll();
}
}
3.8、测试
3.8.1、刷新maven,并安装模块
刷新maven
跳过测试,安装模块
3.8.2、添加tomcat,并将maven-web模块部署到tomcat中
3.8.3、启动tomcat,在浏览器中测试
4、使用父子工程可能存在的问题是什么?
1、jar包依赖冲突问题
5、课堂编程
-项目需求
使用父子工程的方式完成用户管理模块的开发
1、用户登陆
2、显示用户列表
-实现思路
1、创建父工程user-manager
2、创建子模块user-domain完成实体层的开发
3、创建子模块user-dao完成数据库访问层的开发(要求使用MyBatis)
4、创建子模块user-service完成业务层的开发
5、创建子模块user-controller完成控制层的开发
6、课堂小结
切片二:解决jar包依赖冲突问题
2.1、为什么要解决jar包依赖冲突问题?
当我们在maven-dao模块添加了如下坐标
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.14</version>
</dependency>
然后在maven-service模块添加了如下坐标
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.3.10</version>
</dependency>
此时项目中使用的是哪个版本的log4j?此时就产生了依赖冲突,因为service模块要依赖dao模块,但是现在有两个不同版本的jar包
2.2、如何解决jar包依赖冲突问题?
2.2.1、依赖调解原则
maven 自动按照下边的原则调解:
1、第一声明者优先原则
在 pom 文件定义依赖,如果是同级的深度话,以先声明的依赖为准。
2、路径近者优先原则
例如:还是上述情况,maven-dao传递过来 log4j,那如果直接把 log4j 的依赖直接写service到 pom 文件中,那么项目就不会再使用其他依赖传递来的log4j,因为自己直接在 pom 中定义 log4j 要比其他依赖传递过来的路径要近。
2.2.2、 方法一:排除依赖
上边的问题也可以通过排除依赖方法辅助依赖调解,如下:
<dependency>
<groupId>com.woniu</groupId>
<artifactId>maven-dao</artifactId>
<version>1.0-SNAPSHOT</version>
<exclusions>
<exclusion>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
</exclusion>
</exclusions>
</dependency>
2.2.3、 方法二:锁定版
面对众多的依赖,有一种方法不用考虑依赖路径、声明优化等因素可以采用直接锁定版本的方法确定依赖构件的版本,版本锁定后则不考虑依赖的声明顺序或依赖的路径,以锁定的版本的为准添加到工程中,此方法在企业开发中常用。
<?xml version="1.0" encoding="UTF-8"?>
<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/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.woniu</groupId>
<artifactId>com-woniu-dao</artifactId>
<version>1.0-SNAPSHOT</version>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.6</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.1.10</version>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
<scope>test</scope>
</dependency>
</dependencies>
</project>
还可以把版本号提取出来,使用标签设置成变量。
<properties>
<mybatis.version>3.5.6</mybatis.version>
<druid.version>1.1.10</druid.version>
</properties>
上边添加的依赖并没有指定版本,原因是已在中锁定了版本,所以在下不需要再指定版本。
切片三:Maven私服
3.1、为什么要建设Maven私服?
正式开发,不同的项目组开发不同的工程。ssm_dao 工程开发完毕,发布到私服。ssm_service 从私服下载 dao
3.2、什么是Maven私服?
公司在自己的局域网内搭建自己的远程仓库服务器,称为私服,私服服务器即是公司内部的 maven 远程仓库,每个员工的电脑上安装 maven 软件并且连接私服服务器,员工将自己开发的项目打成 jar 并发布到私服服务器,其它项目组从私服服务器下载所依赖的构件(jar)。
私服还充当一个代理服务器,当私服上没有 jar 包会从互联网中央仓库自动下载,如下
3.3、如何搭建Maven私服?
3.3.1、搭建私服环境
第1步:下载 nexus
Nexus 是 Maven 仓库管理器,通过 nexus 可以搭建 maven 仓库,同时 nexus 还提供强大的仓库管理功能,构件搜索功能等。下载 Nexus, 下载地址
将资料中的私服解压放置在一个不带中文件路径下
以管理员身份运行命令提示符工具切换到刚解压的私服文件bin目录
使用命令安装私服:nexus.exe /install
#### 第2步:停止私服
以管理员身份运行命令提示符工具切换到刚解压的私服文件bin目录
输入停止命令:nexus.exe /stop
第3步:查找私服端口
找到解压目录下的nexus-3.33.0-01-win64\nexus-3.33.0-01\etc\nexus-default.properties
# nexus访问端口
application-port=8081
# nexus 主机监听配置(不用修改)
application-host=0.0.0.0
# nexus 工程目录
nexus-webapp=${bundleBasedir}/nexus
nexus-webapp-context-path=/nexus
# nexus 的 web 访问路径
nexus-work=${bundleBasedir}/../sonatype-work/nexus
# nexus 仓库目录
runtime=${bundleBasedir}/nexus/WEB-INF # nexus 运行程序目录
第4步:访问私服
在浏览器中使用url访问私服:http://localhost:8081/
看到网页后需要登录,旧版的.帐户为:admin ,密码为:admin123
nuxus3的初始密码保存在nexus安装目录下的sonatype-work的admin.password文件中,打开文件可以看到如下内容:
提示:内容即为密码明文,而非加密后的结果,直接复制即可。第一次输入账号密码后,会提示修改初始密码
第5步:nexus仓库类型
nexus 的仓库有 4 种类型:
1、hosted,宿主仓库,部署自己的 jar 到这个类型的仓库,包括 releases 和 snapshot 两部分,Releases 公司内部发布版本仓库、 Snapshots 公司内部测试版本仓库,hosted仓库只面向公司内部局域网,3rd party为第三方仓库,意思是当局域网内需要网上(不是我们写的包)的第三方包时,先从网上maven官网下载下来,下载某个本地电脑,然后上传到3rd party这个仓库中
2、proxy,代理仓库,用于代理远程的公共仓库,如 maven 中央仓库,用户连接私服,私服自动去中央仓库下载 jar 包或者插件。当我们的私服没有jar时,去中央仓库下载,下载下来后,全部放到Central这个proxy仓库中,其中Apache Snapshots仓库专门用来存储从apache的中央仓库 中下载下来的
3、group,仓库组,用来合并多个 hosted/proxy 仓库,通常我们配置自己的 maven 连接仓库组。
4、virtual(虚拟):兼容 Maven1 版本的 jar 或者插件,基本上用不到了
nexus 仓库默认在 sonatype-work 目录中:
3.3.2、上传jar包到私服
企业中多个团队协作开发通常会将一些公用的组件、开发模块等发布到私服供其它团队或模块开发人员使用。本例子假设多团队分别开发 maven-domain,maven-dao,maven-service,maven-web,某个团队开发完在maven-dao 会将 maven-dao 发布到私服供 maven-service团队使用,本例子会将 maven-parent 工程打成jar 包发布到私服。
打开本地maven\conf\settings.xml在节点下添加私服登录帐号和密码
<!--配置要访问的私服帐号与密码-->
<server>
<id>releases</id>
<username>admin</username>
<password>admin123</password>
</server>
<server>
<id>snapshots</id>
<username>admin</username>
<password>admin123</password>
</server>
在要上传到私服中的项目上配置上传路径,在ssm项目的父工程pom.xml中添加如下配置
<!--配置上传jar包到maven私服中的路径-->
<distributionManagement>
<!--公司内部仓库-->
<repository>
<id>releases</id>
<name>maven-releases</name>
<url>http://localhost:8081/repository/maven-releases/</url>
</repository>
<!--公司测试仓库-->
<snapshotRepository>
<id>snapshots</id>
<name>maven-snapshots</name>
<url>http://localhost:8081/repository/maven-snapshots/</url>
</snapshotRepository>
</distributionManagement>
注意:pom.xml这里id和settings.xml配置id对应!并且要配置在坐标上面否则会报错
将项目中的jar包上传到私服
在右侧maven工具栏中找到父工程下的lifecycle中的deploy命令执行上传操作
3.3.3、上传jar包到私服
没有配置 nexus 之前,如果本地仓库没有,去中央仓库下载,通常在企业中会在局域网内部署一台私服服务器,有了私服本地项目首先去本地仓库找 jar,如果没有找到则连接私服从私服下载 jar 包,如果私服没有 jar 包私服同时作为代理服务器从中央仓库下载 jar 包,
这样做的好处是一方面由私服对公司项目的依赖 jar 包统一管理,一方面提高下载速度项目连接私服下载 jar 包的速度要比项目连接中央仓库的速度快的多。
本例子测试从私服下载maven-dao包
第1步:在本地maven的settings.xml中配置下载路径
<!-- 下载jar包配置 -->
<profile>
<!--profile的id -->
<id>dev</id>
<repositories>
<repository>
<!--仓库id,repositories可以配置多个仓库,保证id不重复 -->
<id>nexus</id>
<!--仓库地址,即nexus仓库组的地址 -->
<url>http://localhost:8081/repository/maven-public/</url>
<!--是否下载releases构件 -->
<releases>
<enabled>true</enabled>
</releases>
<!--是否下载snapshots构件 -->
<snapshots>
<enabled>true</enabled>
</snapshots>
</repository>
</repositories>
<pluginRepositories>
<!-- 插件仓库,maven的运行依赖插件,也需要从私服下载插件 -->
<pluginRepository>
<!-- 插件仓库的id不允许重复,如果重复后边配置会覆盖前边 -->
<id>public</id>
<name>Public Repositories</name>
<url>http://localhost:8081/repository/maven-public/</url>
</pluginRepository>
</pluginRepositories>
</profile>
第2步:在本地maven的settings.xml中配置激活下载
找到maven本地仓库中项目的打包地址
将maven-dao删除
发布项目,发现提示找不到maven-dao.jar
配置本地maven的settings.xml,设置从私服下载jar
<!--激活下载-->
<activeProfiles>
<activeProfile>dev</activeProfile>
</activeProfiles>
重新发布项目将会自动下载maven-dao包