创建子工程webui:new maven module-module name:mycrowdfunding02-admin-webui-maven-archetype-webapp,注意是web工程
创建子工程component:new maven module-module name:mycrowdfunding03-admin-component-maven-archetype-quickstart
创建子工程entity:new maven module-module name:mycrowdfunding04-admin-entity-maven-archetype-quickstart
创建独立工程:new maven project-create a simple project-finish
group id:com.cc.crowdfunding artifact id:mycrowdfunding05-comon-util packaging:jar 创建独立工程:new maven project-create a simple project-finish group id:com.cc.crowdfunding artifact id:mycrowdfunding06-comon-reverse packaging:jar 配置模块依赖关系(配置pom文件): webui 依赖 componet <dependency> <groupId>com.cc.crowdfunding</groupId> <artifactId>mycrowdfunding03-admin-component</artifactId> <version>0.0.1-SNAPSHOT</version> </dependency> componet 依赖 entiy componet 依赖 util <dependency> <groupId>com.cc.crowdfunding</groupId> <artifactId>mycrowdfunding04-admin-entity</artifactId> <version>0.0.1-SNAPSHOT</version> </dependency> <dependency> <groupId>com.cc.crowdfunding</groupId> <artifactId>mycrowdfunding05-common-util</artifactId> <version>0.0.1-SNAPSHOT</version> </dependency> 结果执行逆向生成操作的 Maven 命令:pom.xml右键 --- run as-maven build --- Goals:mybatis-generator:generate
会在指定目录的entity包下生成Admin.java、AdminExample.java,在mapper包下生成AdminMapper.java、AdminMapper.xml,在Admin.java补充有参无参构造器+tostring方法
将生成的逆向工程文件放到子工程中:com.cc.crowd.entity包整体移动到entity子工程下;component子工程src/main/java目录下创建com.cc.crowd.mapper包,将AdminMapper.java移过来;webui子工程src/main/resources目录下创建mybatis.mapper包,将AdminMapper.xml移过来
parent工程 — 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"> <modelVersion>4.0.0</modelVersion> <groupId>com.cc.crowdfunding</groupId> <artifactId>mycrowdfunding01-admin-parent</artifactId> <version>0.0.1-SNAPSHOT</version> <packaging>pom</packaging> <modules> <module>mycrowdfunding02-admin-webui</module> <module>mycrowdfunding03-admin-component</module> <module>mycrowdfunding04-admin-entity</module> </modules> <properties> <!-- 声明属性, 对 Spring 的版本进行统一管理 --> <atguigu.spring.version>4.3.20.RELEASE</atguigu.spring.version> <!-- 声明属性, 对 SpringSecurity 的版本进行统一管理 --> <atguigu.spring.security.version>4.2.10.RELEASE</atguigu.spring.security.version> </properties> <dependencyManagement> <dependencies> <!-- 1.Spring 依赖 --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-orm</artifactId> <version>${atguigu.spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>${atguigu.spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-test</artifactId> <version>${atguigu.spring.version}</version> </dependency> <!-- 使aop正常工作 --> <dependency> <groupId>org.aspectj</groupId> <artifactId>aspectjweaver</artifactId> <version>1.9.2</version> </dependency> <dependency> <groupId>cglib</groupId> <artifactId>cglib</artifactId> <version>2.2</version> </dependency> <!-- 2.数据库依赖 --> <!-- MySQL 驱动 --> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>8.0.15</version> </dependency> <!-- 数据源 --> <dependency> <groupId>com.alibaba</groupId> <artifactId>druid</artifactId> <version>1.0.31</version> </dependency> <!-- MyBatis --> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis</artifactId> <version>3.2.8</version> </dependency> <!-- MyBatis 与 Spring 整合 --> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis-spring</artifactId> <version>1.2.2</version> </dependency> <!-- MyBatis 分页插件 --> <dependency> <groupId>com.github.pagehelper</groupId> <artifactId>pagehelper</artifactId> <version>4.0.0</version> </dependency> <!-- 3.日志依赖 --> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-api</artifactId> <version>1.7.7</version> </dependency> <dependency> <groupId>ch.qos.logback</groupId> <artifactId>logback-classic</artifactId> <version>1.2.3</version> </dependency> <!-- 其他日志框架的中间转换包 --> <dependency> <groupId>org.slf4j</groupId> <artifactId>jcl-over-slf4j</artifactId> <version>1.7.25</version> </dependency> <dependency> <groupId>org.slf4j</groupId> <artifactId>jul-to-slf4j</artifactId> <version>1.7.25</version> </dependency> <!-- 4.其他依赖 --> <!-- Spring 进行 JSON 数据转换依赖 --> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-core</artifactId> <version>2.9.8</version> </dependency> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-databind</artifactId> <version>2.9.8</version> </dependency> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-annotations</artifactId> <version>2.9.8</version> </dependency> <!-- JSTL 标签库 --> <dependency> <groupId>jstl</groupId> <artifactId>jstl</artifactId> <version>1.2</version> </dependency> <!-- junit 测试 --> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.12</version> <scope>test</scope> </dependency> <!-- 引入 Servlet 容器中相关依赖 --> <dependency> <groupId>javax.servlet</groupId> <artifactId>servlet-api</artifactId> <version>2.5</version> <scope>provided</scope> </dependency> <!-- JSP 页面使用的依赖 --> <dependency> <groupId>javax.servlet.jsp</groupId> <artifactId>jsp-api</artifactId> <version>2.1.3-b06</version> <scope>provided</scope> </dependency> <!-- gson --> <dependency> <groupId>com.google.code.gson</groupId> <artifactId>gson</artifactId> <version>2.8.5</version> </dependency> <!-- SpringSecurity 标签库 --> <dependency> <groupId>org.springframework.security</groupId> <artifactId>spring-security-taglibs</artifactId> <version>4.2.10.RELEASE</version> </dependency> <dependency> <groupId>org.webjars.bower</groupId> <artifactId>jquery</artifactId> <version>3.2.1</version> </dependency> <dependency> <groupId>org.springframework.security</groupId> <artifactId>spring-security-web</artifactId> <version>4.2.10.RELEASE</version> </dependency> <dependency> <groupId>org.springframework.security</groupId> <artifactId>spring-security-config</artifactId> <version>4.2.10.RELEASE</version> </dependency> </dependencies> </dependencyManagement> </project>不同日志系统的整合
转换日志框架
修改日志框架,修改component子工程下pom.xml,添加如下依赖
<dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-api</artifactId> </dependency> <dependency> <groupId>ch.qos.logback</groupId> <artifactId>logback-classic</artifactId> </dependency> <!-- 其他日志框架的中间转换包 --> <dependency> <groupId>org.slf4j</groupId> <artifactId>jcl-over-slf4j</artifactId> </dependency> 由于webui工程依赖component工程,需要把两个工程中Spring自带的comons-loging日志框架移除 component:pom.xml <dependency> <groupId>org.springframework</groupId> <artifactId>spring-orm</artifactId> <exclusions> <exclusion> <groupId>commons-logging</groupId> <artifactId>commons-logging</artifactId> </exclusion> </exclusions> </dependency> webui:pom.xml <dependency> <groupId>org.springframework</groupId> <artifactId>spring-test</artifactId> <scope>test</scope> <exclusions> <exclusion> <groupId>commons-logging</groupId> <artifactId>commons-logging</artifactId> </exclusion> </exclusions> </dependency> 配置日志框架 <?xml version="1.0" encoding="UTF-8"?> <configuration debug="true"> <!-- 指定日志输出的位置 --> <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender"> <encoder> <!-- 日志输出的格式 --> <!-- 按照顺序分别是:时间、日志级别 -5占5个字符、线程名称、打印日志的类、日志主体内容、换行 --> <pattern>[%d{HH:mm:ss}] [%-5level ] [%thread ] [%logger] %msg%n</pattern> </encoder> </appender> <!-- 设置全局日志级别。日志级别按顺序分别是:DEBUG、INFO、WARN、ERROR --> <root level="INFO"> <!-- 指定打印日志的appender,这里通过"STDOUT"引用了前面配置的appender --> <appender-ref ref="STDOUT"/> </root> <!-- 根据特殊需求指定局部日志级别:sql需要debug级别才会打印日志--> <logger name="com.cc.crowd.mapper" level="DEBUG"/> </configuration>声明式事务
基于注解的声明式事务
@Transactional(xxx) public class adminService{ public void insert(){ //... } } 配置数据源dataSource 配置事务管理器DataSourceTransactionManager 开启<tx:annotation-driven>注解驱动 基于xml的声明式事务思路切入点表达式:定位在核心操作上 切入点表达式包含 tx:advice 和 aop:pointcut tx:advice 配置传播行为、隔离级别、回滚异常、只读属性、超时属性
创建 Spring 配置文件:spring-persist-tx.xml <?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" xmlns:tx="http://www.springframework.org/schema/tx" xmlns:aop="http://www.springframework.org/schema/aop" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.3.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.3.xsd"> <!-- 配置自动扫描的包:主要是为了把Service扫描到IOC容器中 --> <context:component-scan base-package="com.cc.crowd.service"/> <!-- 配置事务管理器 --> <bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <!-- 数据源在 spring-persist-mybatis.xml 文件中 现在报错但是实际运行在IOC容器中能找到--> <property name="dataSource" ref="dataSource"/> </bean> <!-- 配置事务通知 --> <tx:advice id="txAdvice" transaction-manager="txManager"> <tx:attributes> <!-- 查询方法:配置只读属性,让数据库知道这是一个查询操作,能够进行一定优化 --> <tx:method name="get*" read-only="true"/> <tx:method name="find*" read-only="true"/> <tx:method name="query*" read-only="true"/> <tx:method name="count*" read-only="true"/> <!-- 增删改方法:配置事务传播行为、回滚异常 --> <!-- propagation属性: REQUIRED:默认值,表示当前方法必须工作在事务中,如果当前线程上没有已经开启的事务,则自己开新事务。如果已经有了,那么就使用这个已有的事务。 顾虑:用别人的事务有可能被因为别人回滚从而导致自己回滚。 REQUIRES_NEW:建议使用的值,表示不管当前线程上有没有事务,都要自己开事务,在自己的事务中运行。 好处:不会受到其他事务回滚的影响。 --> <!-- rollback-for属性:配置事务方法针对什么样的异常回滚 默认:运行时异常回滚 建议:编译时异常和运行时异常都回滚 --> <tx:method name="save*" propagation="REQUIRES_NEW" rollback-for="java.lang.Exception"/> <tx:method name="update*" propagation="REQUIRES_NEW" rollback-for="java.lang.Exception"/> <tx:method name="remove*" propagation="REQUIRES_NEW" rollback-for="java.lang.Exception"/> <tx:method name="batch*" propagation="REQUIRES_NEW" rollback-for="java.lang.Exception"/> </tx:attributes> </tx:advice> <!-- 配置事务切面 --> <aop:config> <!-- 考虑到后面我们整合 SpringSecurity,避免把 UserDetailsService 加入事务控制,让切入点表达式定位到ServiceImpl --> <!-- 定位到具体方法 expression="execution(public void com.cc.crowd.service.AdminService.saveAdmin(Admin admin)"--> <aop:pointcut expression="execution(* *..*ServiceImpl.*(..))" id="txPointcut"/> <!-- 将切入点表达式和事务通知关联起来 --> <aop:advisor advice-ref="txAdvice" pointcut-ref="txPointcut"/> </aop:config> <bean id="bCryptPasswordEncoder" class="org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder"/> </beans>