项目实战07——SSM转SpringBoot

学习目标:

  • SpringBoot框架搭建
  • 无缝转移项目
  • 利用SpringBoot特性做修改

迁移pom文件

在pom文件中先删除SpringMVC、junit 、mybatis,然后迁移到springboot项目中。


迁移dao文件

将src/main/resources文件下的jdbc.properties迁移到springboot的application.properties文件,再将logback.xmlmybatis-config.xml以及水印图片watermark.jpg都移动到springboot的resources文件下。

springboot讲究去xml化,所以很多xml配置文件我们就不迁移到springboot中,而是用代码来代替他的功能,将它写成类的配置。首先在MVC项目中的resources/spring下的spring-dao.xml文件中,我们配置了datasourcesSqlSessionFactory等启动一个bean,但是扫描dao接口包呢在springboot中会启动全package扫描,所以不用配置。然后我们在springboot中创建com/imooc/o2o/config/dao的DataSourceConfiguration.java:

/**
 * 配置datasource到ioc容器里面
 * 
 */
@Configuration
// 配置mybatis mapper的扫描路径
@MapperScan("com.imooc.o2o.dao")
public class DataSourceConfiguration {
	@Value("${jdbc.driver}")
	private String jdbcDriver;
	@Value("${jdbc.url}")
	private String jdbcUrl;
	@Value("${jdbc.username}")
	private String jdbcUsername;
	@Value("${jdbc.password}")
	private String jdbcPassword;

	/**
	 * 生成与spring-dao.xml对应的bean dataSource
	 * 
	 * @return
	 * @throws PropertyVetoException
	 */
	@Bean(name = "dataSource")
	public ComboPooledDataSource createDataSource() throws PropertyVetoException {
		// 生成datasource实例
		ComboPooledDataSource dataSource = new ComboPooledDataSource();
		// 跟配置文件一样设置以下信息
		// 驱动
		dataSource.setDriverClass(jdbcDriver);
		// 数据库连接URL
		dataSource.setJdbcUrl(jdbcUrl);
		// 设置用户名
		dataSource.setUser(DESUtil.getDecryptString(jdbcUsername));
		// 设置用户密码
		dataSource.setPassword(DESUtil.getDecryptString(jdbcPassword));
		// 配置c3p0连接池的私有属性
		// 连接池最大线程数
		dataSource.setMaxPoolSize(30);
		// 连接池最小线程数
		dataSource.setMinPoolSize(10);
		// 关闭连接后不自动commit
		dataSource.setAutoCommitOnClose(false);
		// 连接超时时间
		dataSource.setCheckoutTimeout(10000);
		// 连接失败重试次数
		dataSource.setAcquireRetryAttempts(2);
		return dataSource;
	}

}

然后创建SessionFactoryConfiguration.java:

@Configuration
public class SessionFactoryConfiguration {
	// mybatis-config.xml配置文件的路径
	private static String mybatisConfigFile;

	@Value("${mybatis_config_file}")
	public void setMybatisConfigFile(String mybatisConfigFile) {
		SessionFactoryConfiguration.mybatisConfigFile = mybatisConfigFile;
	}

	// mybatis mapper文件所在路径
	private static String mapperPath;

	@Value("${mapper_path}")
	public void setMapperPath(String mapperPath) {
		SessionFactoryConfiguration.mapperPath = mapperPath;
	}

	// 实体类所在的package
	@Value("${type_alias_package}")
	private String typeAliasPackage;

	@Autowired
	private DataSource dataSource;

	/**
	 * 创建sqlSessionFactoryBean 实例 并且设置configtion 设置mapper 映射路径 设置datasource数据源
	 * 
	 * @return
	 * @throws IOException
	 */
	@Bean(name = "sqlSessionFactory")
	public SqlSessionFactoryBean createSqlSessionFactoryBean() throws IOException {
		SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();
		// 设置mybatis configuration 扫描路径
		sqlSessionFactoryBean.setConfigLocation(new ClassPathResource(mybatisConfigFile));
		// 添加mapper 扫描路径
		PathMatchingResourcePatternResolver pathMatchingResourcePatternResolver = new PathMatchingResourcePatternResolver();
		String packageSearchPath = ResourcePatternResolver.CLASSPATH_ALL_URL_PREFIX + mapperPath;
		sqlSessionFactoryBean.setMapperLocations(pathMatchingResourcePatternResolver.getResources(packageSearchPath));
		// 设置dataSource
		sqlSessionFactoryBean.setDataSource(dataSource);
		// 设置typeAlias 包扫描路径
		sqlSessionFactoryBean.setTypeAliasesPackage(typeAliasPackage);
		return sqlSessionFactoryBean;
	}

}

然后我们将MVC中的daoentityutil以及src/main/resources下的mapper文件都迁移到springboot中,然后将ut中的AreaDaoTest.java移进来,然后因为我们不用xml文件了,测试类中也没有了BaseTest类,所以不用继承BaseTest,取而代之的是@RunWith(SpringRunner.class)@SpringBootTest两个注解。至此,dao层迁移成功。


迁移service文件

接下来是service层的迁移,在spring-service.xml配置文件中,一个是配置事务管理器,有bean标签,我们可以用代码的方式实现,然后是配置基于注解的声明式事务,这个有一个tx:annotation-driven标签,不能写入bean,我们可以用继承的方式来实现。

同理,我们在config文件下创建service文件,然后写一个TransactionManagementConfuguration.java:

/**
 * 对标spring-service里面的transactionManager
 * 继承TransactionManagementConfigurer是因为开启annotation-driven
 *
 */
@Configuration
// 首先使用注解 @EnableTransactionManagement 开启事务支持后
// 在Service方法上添加注解 @Transactional 便可
@EnableTransactionManagement
public class TransactionManagementConfiguration implements TransactionManagementConfigurer {

	@Autowired
	// 注入DataSourceConfiguration里边的dataSource,通过createDataSource()获取
	private DataSource dataSource;

	@Override
	/**
	 * 关于事务管理,需要返回PlatformTransactionManager的实现
	 */
	public PlatformTransactionManager annotationDrivenTransactionManager() {
		return new DataSourceTransactionManager(dataSource);
	}

}

接下来是spring-redis.xml配置文件的迁移,因为偶我们在src/main/resources下的redis.properties文件配置了redis的相关信息,所以我们将该文件下的配置信息转移到springboot的application.properties文件。然后将spring-redis.xml文件转换为springboot的config/redis的RedisConfiguration.java中:

/**
 * spring-redis.xml里的配置
 *
 */
@Configuration
public class RedisConfiguration {
	@Value("${redis.hostname}")
	private String hostname;
	@Value("${redis.port}")
	private int port;
	@Value("${redis.pool.maxActive}")
	private int maxTotal;
	@Value("${redis.pool.maxIdle}")
	private int maxIdle;
	@Value("${redis.pool.maxWait}")
	private long maxWaitMillis;
	@Value("${redis.pool.testOnBorrow}")
	private boolean testOnBorrow;

	@Autowired
	private JedisPoolConfig jedisPoolConfig;
	@Autowired
	private JedisPoolWriper jedisWritePool;
	@Autowired
	private JedisUtil jedisUtil;

	/**
	 * 创建redis连接池的设置
	 * 
	 * @return
	 */
	@Bean(name = "jedisPoolConfig")
	public JedisPoolConfig createJedisPoolConfig() {
		JedisPoolConfig jedisPoolConfig = new JedisPoolConfig();
		// 控制一个pool可分配多少个jedis实例
		jedisPoolConfig.setMaxTotal(maxTotal);
		// 连接池中最多可空闲maxIdle个连接 ,这里取值为20,
		// 表示即使没有数据库连接时依然可以保持20空闲的连接,
		// 而不被清除,随时处于待命状态。
		jedisPoolConfig.setMaxIdle(maxIdle);
		// 最大等待时间:当没有可用连接时,
		// 连接池等待连接被归还的最大时间(以毫秒计数),超过时间则抛出异常
		jedisPoolConfig.setMaxWaitMillis(maxWaitMillis);
		// 在获取连接的时候检查有效性
		jedisPoolConfig.setTestOnBorrow(testOnBorrow);
		return jedisPoolConfig;
	}

	/**
	 * 创建Redis连接池,并做相关配置
	 * 
	 * @return
	 */
	@Bean(name = "jedisWritePool")
	public JedisPoolWriper createJedisPoolWriper() {
		JedisPoolWriper jedisPoolWriper = new JedisPoolWriper(jedisPoolConfig, hostname, port);
		return jedisPoolWriper;
	}

	/**
	 * 创建Redis工具类,封装好Redis的连接以进行相关的操作
	 * 
	 * @return
	 */
	@Bean(name = "jedisUtil")
	public JedisUtil createJedisUtil() {
		JedisUtil jedisUtil = new JedisUtil();
		jedisUtil.setJedisPool(jedisWritePool);
		return jedisUtil;
	}

	/**
	 * Redis的key操作
	 * 
	 * @return
	 */
	@Bean(name = "jedisKeys")
	public JedisUtil.Keys createJedisKeys() {
		JedisUtil.Keys jedisKeys = jedisUtil.new Keys();
		return jedisKeys;
	}

	/**
	 * Redis的Strings操作
	 * 
	 * @return
	 */
	@Bean(name = "jedisStrings")
	public JedisUtil.Strings createJedisStrings() {
		JedisUtil.Strings jedisStrings = jedisUtil.new Strings();
		return jedisStrings;
	}
}

然后将dto、enums、exceptions、service、util包转移到spring boot项目中去。然后用service的测试类AreaServiceTest.java、WechatAuthServiceTest.java来测试。


接下来是web层,同样,在config/web的MvcConfiguration.java进行类的配置来代替MVC中spring-web.xml配置文件,

/**
 * 开启Mvc,自动注入spring容器。 WebMvcConfigurerAdapter:配置视图解析器
 * 当一个类实现了这个接口(ApplicationContextAware)之后,这个类就可以方便获得ApplicationContext中的所有bean
 *
 */
@Configuration
// 等价于<mvc:annotation-driven/>
@EnableWebMvc
public class MvcConfiguration extends WebMvcConfigurerAdapter implements ApplicationContextAware {
	// Spring容器
	private ApplicationContext applicationContext;

	@Override
	public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
		this.applicationContext = applicationContext;
	}

	/**
	 * 静态资源配置
	 * 
	 * @param registry
	 */
	@Override
	public void addResourceHandlers(ResourceHandlerRegistry registry) {
		// registry.addResourceHandler("/resources/**").addResourceLocations("classpath:/resources/");
//		registry.addResourceHandler("/upload/**").addResourceLocations("file:/Users/baidu/work/image/upload/");
		registry.addResourceHandler("/upload/**")
                .addResourceLocations("file:/D:/projectdev/image/upload/");
	}

	/**
	 * 定义默认的请求处理器
	 */
	@Override
	public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
		configurer.enable();
	}

	/**
	 * 创建viewResolver
	 * 
	 * @return
	 */
	@Bean(name = "viewResolver")
	public ViewResolver createViewResolver() {
		InternalResourceViewResolver viewResolver = new InternalResourceViewResolver();
		// 设置Spring 容器
		viewResolver.setApplicationContext(this.applicationContext);
		// 取消缓存
		viewResolver.setCache(false);
		// 设置解析的前缀
		viewResolver.setPrefix("/WEB-INF/html/");
		// 设置试图解析的后缀
		viewResolver.setSuffix(".html");
		return viewResolver;
	}

	/**
	 * 文件上传解析器
	 * 
	 * @return
	 */
	@Bean(name = "multipartResolver")
	public CommonsMultipartResolver createMultipartResolver() {
		CommonsMultipartResolver multipartResolver = new CommonsMultipartResolver();
		multipartResolver.setDefaultEncoding("utf-8");
		// 1024 * 1024 * 20 = 20M
		multipartResolver.setMaxUploadSize(20971520);
		multipartResolver.setMaxInMemorySize(20971520);
		return multipartResolver;
	}

	@Value("${kaptcha.border}")
	private String border;

	@Value("${kaptcha.textproducer.font.color}")
	private String fcolor;

	@Value("${kaptcha.image.width}")
	private String width;

	@Value("${kaptcha.textproducer.char.string}")
	private String cString;

	@Value("${kaptcha.image.height}")
	private String height;

	@Value("${kaptcha.textproducer.font.size}")
	private String fsize;

	@Value("${kaptcha.noise.color}")
	private String nColor;

	@Value("${kaptcha.textproducer.char.length}")
	private String clength;

	@Value("${kaptcha.textproducer.font.names}")
	private String fnames;

	/**
	 * 由于web.xml不生效了,需要在这里配置Kaptcha验证码Servlet
	 */
	@Bean
	public ServletRegistrationBean servletRegistrationBean() throws ServletException {
		ServletRegistrationBean servlet = new ServletRegistrationBean(new KaptchaServlet(), "/Kaptcha");
		servlet.addInitParameter("kaptcha.border", border);// 无边框
		servlet.addInitParameter("kaptcha.textproducer.font.color", fcolor); // 字体颜色
		servlet.addInitParameter("kaptcha.image.width", width);// 图片宽度
		servlet.addInitParameter("kaptcha.textproducer.char.string", cString);// 使用哪些字符生成验证码
		servlet.addInitParameter("kaptcha.image.height", height);// 图片高度
		servlet.addInitParameter("kaptcha.textproducer.font.size", fsize);// 字体大小
		servlet.addInitParameter("kaptcha.noise.color", nColor);// 干扰线的颜色
		servlet.addInitParameter("kaptcha.textproducer.char.length", clength);// 字符个数
		servlet.addInitParameter("kaptcha.textproducer.font.names", fnames);// 字体
		return servlet;
	}

	/**
	 * 添加拦截器配置
	 */
	@Override
	public void addInterceptors(InterceptorRegistry registry) {
		/** 店家管理系统拦截部分 **/
		String interceptPath = "/shopadmin/**";
		// 注册拦截器
		InterceptorRegistration loginIR = registry.addInterceptor(new ShopLoginInterceptor());
		// 配置拦截的路径
		loginIR.addPathPatterns(interceptPath);
		/** shopauthmanagement page **/
		loginIR.excludePathPatterns("/shopadmin/addshopauthmap");
		/** scan **/
		loginIR.excludePathPatterns("/shopadmin/adduserproductmap");
		loginIR.excludePathPatterns("/shopadmin/exchangeaward");
		// 还可以注册其它的拦截器
		InterceptorRegistration permissionIR = registry.addInterceptor(new ShopPermissionInterceptor());
		// 配置拦截的路径
		permissionIR.addPathPatterns(interceptPath);
		// 配置不拦截的路径
		/** shoplist page **/
		permissionIR.excludePathPatterns("/shopadmin/shoplist");
		permissionIR.excludePathPatterns("/shopadmin/getshoplist");
		/** shopregister page **/
		permissionIR.excludePathPatterns("/shopadmin/getshopinitinfo");
		permissionIR.excludePathPatterns("/shopadmin/registershop");
		permissionIR.excludePathPatterns("/shopadmin/shopoperation");
		/** shopmanage page **/
		permissionIR.excludePathPatterns("/shopadmin/shopmanagement");
		permissionIR.excludePathPatterns("/shopadmin/getshopmanagementinfo");
		/** shopauthmanagement page **/
		permissionIR.excludePathPatterns("/shopadmin/addshopauthmap");
		/** scan **/
		permissionIR.excludePathPatterns("/shopadmin/adduserproductmap");
		permissionIR.excludePathPatterns("/shopadmin/exchangeaward");
		/** 超级管理员系统拦截部分 **/
		interceptPath = "/superadmin/**";
		// 注册拦截器
		InterceptorRegistration superadminloginIR = registry.addInterceptor(new SuperAdminLoginInterceptor());
		// 配置拦截的路径
		superadminloginIR.addPathPatterns(interceptPath);
		superadminloginIR.excludePathPatterns("/superadmin/login");
		superadminloginIR.excludePathPatterns("/superadmin/logincheck");
		superadminloginIR.excludePathPatterns("/superadmin/main");
		superadminloginIR.excludePathPatterns("/superadmin/top");
		superadminloginIR.excludePathPatterns("/superadmin/clearcache4area");
		superadminloginIR.excludePathPatterns("/superadmin/clearcache4headline");
		superadminloginIR.excludePathPatterns("/superadmin/clearcache4shopcategory");
	}

}

然后将web文件转移到springboot项目中,web层就转移成功了。


接下来进行前端的操作,然后将src/main里的webapp转移到项目里,然后由于springboot中没有src/main/webapp/WEB-INF/html/web.xml配置文件,所以我们在spring boot的application.propertiesMvcConfiguration.java中配置相关信息来迁移kaptcha验证码。

在mvc中我们在外置tomcat的servers里的server.xml将图片的根路径docBase指定了,但是springboot是内置tomcat的,所以我们需要在MvcConfiguration.java加入相关的类来指定目录。

然后拦截器就是先将mvc中的interceptor包转移到springboot中,然后也是在MvcConfiguration.java中添加addInterceptor方法来指定拦截器。

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值