目录
前言
最近进行spring整合mybatis框架、mvc、redis以及shiro的学习,因为各个部分配置较多,现整理如下,以作查询
一、spring整合mybatis
1.1导入jar包
<dependencies>
<!-- mybatis -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.7</version>
</dependency>
<!-- mybatis-spring -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<version>2.0.6</version>
</dependency>
<!-- spring-context -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.3.13</version>
</dependency>
<!-- mysql-connector-java mysql数据库驱动 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.26</version>
</dependency>
<!-- spring-jdbc spring连接数据库 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>5.3.13</version>
</dependency>
<!-- druid 数据库连接池 -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.2.8</version>
</dependency>
<!-- jackson-databind json类型数据转换 -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.13.0</version>
</dependency>
<!-- lombok 对象的赋值与表现重写 -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.22</version>
<scope>provided</scope>
</dependency>
<!-- spring-test spring要用的测试jar -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>5.3.13</version>
<scope>test</scope>
</dependency>
<!-- junit 单元测试 -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13.2</version>
<scope>test</scope>
</dependency>
</dependencies>
1.2 配置文件
spring-mybatis.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"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd">
<!-- 扫描包 创建对象 -->
<context:component-scan base-package="springPro" />
<!-- 导入数据库连接信息 -->
<context:property-placeholder location="classpath:properties/db.properties" />
<!-- 配置连接池 -->
<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
<property name="driverClassName" value="${jdbc.driver}" />
<property name="url" value="${jdbc.url}" />
<property name="username" value="${jdbc.username}" />
<property name="password" value="${jdbc.password}" />
</bean>
<!-- 配置工厂 -->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<!-- 数据源 -->
<property name="dataSource" ref="dataSource" />
<!-- 类型别名 -->
<property name="typeAliasesPackage" value="springPro.po" />
<!-- 映射文件所在的位置 -->
<property name="mapperLocations" value="classpath:mapper/*.xml" />
<!-- mybatis配置文件的路径 -->
<property name="configLocation" value="classpath:mybatis/mybatis-config.xml" />
</bean>
<!-- 将创建mapper实例的权限交给spring管理 -->
<bean id="configurer" class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<!-- 创建sqlSession工厂的名称 -->
<property name="sqlSessionFactoryBeanName" value="sqlSessionFactory" />
<!-- 需要创建的文件在哪个目录下 -->
<property name="basePackage" value="springPro.mapper" />
</bean>
</beans>
db.properties
jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/库名?useUnicode=true&characterEncoding=UTF8
jdbc.username=******
jdbc.password=******
1.3 测试文件
po.Student
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Student {
private Integer id;
private String name;
private Integer age;
private String gender;
private String address;
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
@JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd HH:mm:ss")
private Date birth;
}
service.StudentService
@Service
public class StudentService {
@Autowired
private StudentMapper studentMapper;
public List<Student> selectAll(){
return studentMapper.selectAll();
}
}
mapper.StudentMapper
public interface StudentMapper {
List<Student> selectAll();
}
resoutces.mapper.StudentMapper.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="springPro.mapper.StudentMapper">
<select id="selectAll" resultType="springPro.po.Student">
select id,name,age,gender,address,birth
from student
</select>
</mapper>
二、spring整合web
2.1 导入jar包
<!-- spring-web -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>5.3.13</version>
</dependency>
<!-- javax.servlet-api -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>4.0.1</version>
<scope>provided</scope>
</dependency>
2.2 配置文件
web.xml
<!DOCTYPE web-app PUBLIC
"-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
"http://java.sun.com/dtd/web-app_2_3.dtd" >
<web-app>
<display-name>Archetype Created Web Application</display-name>
<!-- 指定spring配置文件的位置 -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:spring/spring-service.xml</param-value>
</context-param>
<!-- 配置监听器 web监听spring -->
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
</web-app>
spring-service.xml
<!-- 扫描包 创建对象 -->
<context:component-scan base-package="springPro" />
2.3 测试文件
StudentServlet
@WebServlet("/student")
public class StudentServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
this.doPost(req,resp);
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
WebApplicationContext context = WebApplicationContextUtils.getWebApplicationContext(this.getServletContext());
StudentService service = context.getBean(StudentService.class);
service.springWebTest();
}
}
StudentService
@Service
public class StudentService {
@Autowired
private StudentMapper studentMapper;
public void springWebTest(){
System.out.println("访问service");
}
}
2.4 测试结果
访问service
三、spring——AOP
3.1 AOP额外功能【日志、鉴权、性能】
3.1.1 xml配置方式
3.1.1.1 导入jar包
<!-- spring-aspects -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aspects</artifactId>
<version>5.3.13</version>
</dependency>
3.1.1.2 配置文件
spring-AOP.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: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/aop https://www.springframework.org/schema/aop/spring-aop.xsd">
<!-- 扫描包 创建对象 -->
<context:component-scan base-package="springPro" />
<!-- 配置切面 -->
<bean id="logAspect" class="springPro.aspect.logAspect" />
<!-- aop:额外功能 -->
<aop:config>
<!-- 指定切点 execution() 织语表达式,找到要生成动态代理的所有类 -->
<aop:pointcut id="pointcut" expression="execution(public * springPro.service..*.*(..))"/>
<!-- 指定切面 -->
<aop:aspect ref="logAspect">
<!-- 功能执行之前 -->
<aop:before method="before" pointcut-ref="pointcut" />
<!-- 功能执行之后 -->
<aop:after method="after" pointcut-ref="pointcut" />
<!-- 功能执行之后报错执行 -->
<aop:after-throwing method="afterThrowing" pointcut-ref="pointcut" />
<!-- 功能执行之后 返回结果时执行 -->
<aop:after-returning method="afterReturning" pointcut-ref="pointcut" />
<!-- 包含其余四个 环绕形 -->
<!-- <aop:around method="around" pointcut-ref="pointcut" />-->
</aop:aspect>
</aop:config>
</beans>
3.1.1.3 测试文件
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:spring/spring-service.xml")
public class xmlTest {
@Autowired
private StudentService studentService;
@Test
public void test01(){
studentService.springWebTest();
}
}
3.1.1.4 测试结果
在方法调用之前我执行了
访问service
在方法调用之后我执行了
在方法调用之后 返回结果之前我执行了
3.1.2 注解配置方式
3.1.2.1 导入jar包
<!-- spring-aspects -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aspects</artifactId>
<version>5.3.13</version>
</dependency>
3.1.2.2 配置文件
spring-AOP.xml
<aop:aspectj-autoproxy />
3.1.2.3 测试文件
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:spring/spring-service.xml")
public class annotationTest {
@Autowired
private StudentService studentService;
@Test
public void test01(){
studentService.springWebTest();
}
}
3.1.2.4 测试结果
在方法调用之前我执行了
访问service
在方法调用之后 返回结果之前我执行了
在方法调用之后我执行了
3.2 AOP事务功能
3.2.1 xml配置方式
3.2.1.1 导入jar包
<!-- spring-aspects -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aspects</artifactId>
<version>5.3.13</version>
</dependency>
3.2.1.2 配置文件
spring-aop.xml
<!-- 导入数据库连接信息 -->
<context:property-placeholder location="classpath:properties/db.properties" />
<!-- 配置连接池 -->
<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
<property name="driverClassName" value="${jdbc.driver}" />
<property name="url" value="${jdbc.url}" />
<property name="username" value="${jdbc.username}" />
<property name="password" value="${jdbc.password}" />
</bean>
<!-- 初始化事务 -->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource" />
</bean>
<!-- 配置事务 -->
<tx:advice id="txAdvice" transaction-manager="transactionManager">
<tx:attributes>
<tx:method name="add*" propagation="REQUIRED"/>
<tx:method name="insert*" propagation="REQUIRED"/>
<tx:method name="save*" propagation="REQUIRED"/>
<tx:method name="update*" propagation="REQUIRED"/>
<tx:method name="modify*" propagation="REQUIRED"/>
<tx:method name="delete*" propagation="REQUIRED"/>
<tx:method name="remove*" propagation="REQUIRED"/>
<tx:method name="select*" propagation="REQUIRED"/>
<tx:method name="find*" propagation="REQUIRED"/>
</tx:attributes>
</tx:advice>
<!-- sop:事务功能 -->
<aop:config>
<!-- 指定切点 execution() 织语表达式,找到要生成动态代理的所有类 -->
<aop:pointcut id="pointcut" expression="execution(public * springPro.service..*.*(..))"/>
<!-- 开启事务 -->
<aop:advisor advice-ref="txAdvice" pointcut-ref="pointcut" />
</aop:config>
3.2.2 注解配置方式
3.2.2.1 导入jar包
<!-- spring-aspects -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aspects</artifactId>
<version>5.3.13</version>
</dependency>
3.2.2.2 配置文件
spring-aop.xml
<!--启用事务注解-->
<tx:annotation-driven transaction-manager="transactionManager"/>
3.2.2.3 在要使用事务的方法上手动加入注解
@Service
public class StudentService {
@Transactional
public int add(int i, int j){
System.out.println("增加的核心功能");
return i+j;
}
}
四、spring——MVC
4.1 导入jar包
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.3.13</version>
</dependency>
4.2 配置文件
web.xml
<!-- spring-MVC 前端控制器 -->
<servlet>
<servlet-name>spring-mvc</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:spring/spring-service.xml</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>spring-mvc</servlet-name>
<!--
/* 指任何文件 示例 /a,/a.jsp,/a.jpg
/ 指不带后缀名 示例 /a,/a/b
servlet->controller C层带的一般是路径 所以不带后缀名
-->
<url-pattern>/</url-pattern>
</servlet-mapping>
spring-MVC.xml
<!-- 扫描包 创建对象 -->
<context:component-scan base-package="springPro.controller" />
<!-- 请求映射器和请求适配器 -->
<!-- 应用控制器-->
<!-- spring3.1之前的写法 -->
<!-- 请求映射器-->
<!--<bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping"></bean>-->
<!-- 请求适配器-->
<!--<bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter"></bean>-->
<!-- 现在的简单写法 -->
<mvc:annotation-driven />
<!-- 视图解析器 -->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<!-- 路径前缀 -->
<property name="prefix" value="/WEB-INF/pages/" />
<!-- 路径后缀 -->
<property name="suffix" value=".jsp" />
</bean>
4.3 测试文件
controller.StudentController
@Controller
@RequestMapping("/student") //窄化处理
public class StudentController {
@RequestMapping("/hello") //方法路径
private String helloWord(){
return "student/list"; // 返回路径 /WEB-INF/pages/student/list
}
}
4.4 测试结果

五、spring整合redis
5.1 导入jar包
<!-- jedis -->
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>3.7.0</version>
<exclusions>
<exclusion>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
</exclusion>
</exclusions>
</dependency>
<!-- spring-data-redis -->
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-redis</artifactId>
<version>2.6.0</version>
<exclusions>
<exclusion>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
</exclusion>
</exclusions>
</dependency>
<!-- slf4j-api -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.32</version>
</dependency>
5.2 配置文件
spring-redis.xml
<!-- 配置连接信息 -->
<bean id="connectionFactory" class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory"
p:hostName="127.0.0.1" p:port="6379" p:password="******" />
<!-- 配置StringRedisTemplate信息 -->
<bean id="stringRedisTemplate" class="org.springframework.data.redis.core.StringRedisTemplate" >
<property name="connectionFactory" ref="connectionFactory" />
</bean>
<!-- 配置RedisTemplate信息 -->
<bean class="org.springframework.data.redis.core.RedisTemplate">
<property name="connectionFactory" ref="connectionFactory" />
</bean>
<!--
StringRedisTemplate和RedisTemplate的区别
StringRedisTemplate继承RedisTemplate,两者使用方法差不多
最大的差别是两者使用的序列化类不同
RedisTemplate使用的是 JdkSerializationRedisSerializer
StringRedisTemplate使用的是 StringRedisSerializer
RedisTemplate存入数据会经过字节转译 存入的数据是字节码 同时取出的数据也必须是字节码 否则会报空
StringRedisTemplate正常存储取出数据
-->
5.3 测试文件
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:spring/spring-redis.xml")
public class RedisTest {
@Autowired
private RedisTemplate<String,Object> redisTemplate;
@Autowired
private StringRedisTemplate stringRedisTemplate;
@Test
public void test01(){
redisTemplate.opsForValue().set("test","这个是测试数据test1");
Object test = redisTemplate.opsForValue().get("test");
System.out.println(test);
}
@Test
public void test02(){
stringRedisTemplate.opsForValue().set("test02","这个是测试数据test02");
String test02 = stringRedisTemplate.opsForValue().get("test02");
System.out.println(test02);
}
}
5.4 测试结果
test01

test02

六、spring整合shiro--认证器
6.1 导入jar包
<!-- shiro-spring -->
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-spring</artifactId>
<version>1.8.0</version>
<exclusions>
<exclusion>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
</exclusion>
</exclusions>
</dependency>
6.2 配置文件
web.xml
<!-- 开启过滤器 指定所有请求都要过滤 -->
<filter>
<filter-name>shiroFilter</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>
<filter-mapping>
<filter-name>shiroFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
spring-shiro.xml
<!-- 设置安全管理器 -->
<bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
<!-- 指定认证器 authenticator -->
<property name="authenticator" ref="authenticator" />
</bean>
<!-- 配置认证器 -->
<bean id="authenticator" class="org.apache.shiro.authc.pam.ModularRealmAuthenticator" >
<!-- 配置认证策略 -->
<property name="authenticationStrategy">
<bean class="org.apache.shiro.authc.pam.AtLeastOneSuccessfulStrategy" />
</property>
<!-- 引入自定义数据源 -->
<property name="realms" ref="realmList" />
</bean>
<!-- 自定义数据源 -->
<utils:list id="realmList">
<bean class="springPro.realms.MyRealm">
<property name="name" value="myRealmName" />
</bean>
</utils:list>
<!-- 配置lifecycleBeanPostProcessor 可以用来自己管理shiroBean的生命周期 -->
<bean id="lifecycleBeanPostProcessor" class="org.apache.shiro.spring.LifecycleBeanPostProcessor" />
<!-- 配置shiro的过滤器 id必须和web.xml中指定的过滤器名称一致 -->
<bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
<!-- 引入安全管理器 -->
<property name="securityManager" ref="securityManager" />
<!-- 指定过滤条件 -->
<property name="filterChainDefinitions">
<value>
<!-- /user/login 可以不经过过滤器直接访问服务器 其余请求都要过滤 -->
/user/login=anon
/**=authc
</value>
</property>
</bean>
6.3 测试文件
MyRealm.java
public class MyRealm extends AuthorizingRealm {
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
return null;
}
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
User user = new User("张三","123456","mySalt");
return new SimpleAuthenticationInfo(user,user.getPassword(),getName());
}
}
UserController.java
@RestController
@RequestMapping("/user")
public class UserController {
@GetMapping("/login")
public void login(){
Subject subject = SecurityUtils.getSubject();
UsernamePasswordToken token = new UsernamePasswordToken("张三","123456");
subject.login(token);
User principal = (User) subject.getPrincipal();
System.out.println(principal);
}
}
6.4 测试结果
User(name=张三, password=123456, salt=mySalt)
6.5 认证器加盐
出于用户数据安全,往往数据库存储的信息并不是可读的数据,而是经过加密处理之后的数据。以用户密码为例,正常情况下,用户登录时输入用户名以及密码,验证时通过用户名从数据库取得用户信息,将数据库中的用户密码和用户输入的密码进行比对,如果相同则登录成功。这时如果数据库存储的如果是可读的用户密码,会产生安全隐患,所以数据库中应该存储不可读的经过加密之后的密码,用户输入用户名密码后,输入的密码会在认证器执行之前经过系统加密转换,将加密后的结果与数据库中的数据进行比对,相同则登陆成功。
6.5.1 md5加密工具
测试文件
package springPro.test;
import org.apache.shiro.crypto.hash.SimpleHash;
import org.junit.Test;
public class Md5Test {
@Test
public void md5Test(){
//SimpleHash hash = new SimpleHash("md5", "123456");
//System.out.println(hash.toHex());
// 加密工具 密码 盐值 加密次数
SimpleHash hash = new SimpleHash("md5", "123456","mySalt",1024);
System.out.println(hash.toHex());
}
}
测试结果
5930e7b52598c68776259c15a274b1ef
6.5.2 加盐配置文件
spring-shiro.xml
主要是在自定义的认证文件中补充加盐信息
<!-- 自定义数据源 -->
<utils:list id="realmList">
<bean class="springPro.realms.MyRealm">
<property name="name" value="myRealmName" />
<!-- 配置加盐方式 -->
<property name="credentialsMatcher">
<bean class="org.apache.shiro.authc.credential.HashedCredentialsMatcher">
<!-- 加盐工具 -->
<property name="hashAlgorithmName" value="md5" />
<!-- 加盐次数 -->
<property name="hashIterations" value="1024" />
</bean>
</property>
</bean>
</utils:list>
myRealm.java
package springPro.realms;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.util.ByteSource;
import springPro.po.User;
public class MyRealm extends AuthorizingRealm {
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
return null;
}
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
//这里应该是从数据库中获取到的用户信息 姓名 密码 盐值 其中密码应该是加密后的数据
User user = new User("张三","5930e7b52598c68776259c15a274b1ef","mySalt");
return new SimpleAuthenticationInfo(user,user.getPassword(), ByteSource.Util.bytes(user.getSalt()),getName());
}
}
696

被折叠的 条评论
为什么被折叠?



