复习常用技术框架

🧐

作者: Ian | 2018-05-19 | 阅读

日志:

Log4j2

配置文件:

  • Log4j2 采用的是.xml、.json或者.jsn
  • Log4j2.xml放置在resource目录下。
  • 也可以修改为 log4j 的配置文件.properties (这个需要到web.xml里面配置监听)

spring

  • 一个分层的JavaSE/EEfull(一站式)轻量级开源框架
  • 特征
    • 轻量:从大小与开销两方面而言Spring都是轻量的,非侵入式
    • 控制反转:通过一种称作控制反转(Ioc)的技术促进了低耦合
    • 面向切面:允许通过分离应用的业务逻辑与系统级服务(例如审计(auditing)和事物(transaction)管理)进行内聚性的开发
    • 容器:包含并管理应用对象的配置和生命周期,在这个意义上它是一种容器。

spring mvc

  • 与struts2的区别
    1. spring mvc和spring是无缝的
    2. struts2是类级别的拦截,spring mvc是方法级别的拦截
    3. spring mvc 的入口是servlet,而struts2是filter
    4. spring mvc 开发效率和性能高于struts2
  • 进行更简洁的web层的开发;
  • 天生与spring框架即成(如Ioc容器、Aop等);
  • 提供强大的约定大于配置的契约式编程支持;
  • 能简单的进行web层的单元测试;
  • 支持灵活的url到页面控制器的映射;

mybatis-plus

  • 一款mybatis的增强crud工具包,简化增删改查操作。启动加载xml配置时注入表单sql操作,为简化开发工作、提高生产率而生。mybatis-plus启动注入非拦截实现、性能更优。
  • 与mybatis相比的优势
    • 增强了mybatis通用单表操作的能力,只需要继承通用的service或者dao就能拥有单表增删改查的能力
    • mybatis-plus启动注入非拦截实现、性能更优
    • 多种ID选择,类型ID_WORKER,UUID全局唯一、支持实现分库
    • 完全继承原生,易理解、扩展使用,支持自定义表、字段、ID动态注解

shiro

一个强大一用的Java安全框架,提供了认证、授权、加密和会话管理等功能,可为任何应用提供安全保障-从命令行应用、移动应用到大型网络及企业应用。

druid监控

  • 替换dbcp和c3p0。Druid提供了一个高效、功能强大、可扩展性好的数据库连接池。
  • 可以监控数据库访问性能,Druid内置提供了一个功能强大的statFilter插件,能够详细统计sql的执行性能,这对于线上分析数据库访问性能有帮助。
  • 数据库密码加密。直接把数据库密码写在配置文件中,这是不好的行为,容易导致安全问题。DruidDruiver和DruidDataSource都支持PasswordCallback。
  • sql执行日志,Druid提供了不同的LogFilter,能够支持Common-Logging、Log4j和JdkLog,你可以按需求选择相应的LogFilter,监控你应用的数据库访问情况。
  • 扩展JDBC,如果你要对JDBC层有编程的需求,可以通过Druid提供的Filter机制,很方便编写JDBC层的扩展插件。

使用redis缓存

pom.xml中将redis放开,将ehcahe注掉! spring-config.xml中把ehcache注掉,把redis放开!

项目常用注解

spring 与 spring mvc

  • @Controller 用于标注控制层组件
  • @Service 服务组件,用于标注业务层组件
  • @Component 泛指组件,当组件不好归类的时候,我们可以使用这个组件进行标注
  • @GetMapping method为get请求的@RequestMapping简写
  • @PostMapping method为post请求的@RequestMapping简写
  • @RequestMapping
    • 处理请求地址映射的注解,可用于类或方法上
    • 用于类上,表示类中的所有相应请求的方法都是以改地址作为父路径
  • @Autowired
    • 对类成员变量、方法及构造函数进行标注,完成自动装配的工作
    • 通过@Autowired的使用来消除set、get方法
    • 默认是按照byType进行注入的
  • @ResponseBody
    • 表示该方法的返回结果直接写入HTTP response body中
    • 一般在异步获取数据时使用,在使用@RequestMapping后,返回值通常解析为跳转路径,加上@responsebody后返回结果不会被解析为跳转路径,而是直接写入http response body中。比如异步获取json数据,加上@responsebody后,会直接返回json数据。
  • @Scheduled spring定时任务注解,使用cron表达式
  • @InitBinder 绑定请求参数到指定的属性编辑器,解决类型的转换问题

spring aop

  • @Pointcut 声明切入点表达式,一般在该方法中不再添加其他代码
  • @Around 环绕通知,围绕着方法执行
  • @Aspect 配置在类上,把这个类声明为一个切面,需要把该类放入到IOC容器中,再声明为一个切面
  • @Order 指定切面的优先级,当有多个切面时,数值越小优先级越高

mybatic plus

  • @TableName 表名注解
  • @TableField 字段注解
  • @TableId 主键注解

其它

  • @CsrfToken 完成检测登录时是否带有token,防止跨站请求伪造攻击
  • @SuppressWarnings 对被批注的代码元素内部的某些警告保持静默
  • @JsonProperty
    • @JsonProperty 此注解用于属性上,作用是把该属性的名称序列化为另外一个名称,如把trueName属性序列化为name,@JsonProperty(name)。
    • 拓展
      • @JsonIgnore 此注解用于属性上,作用是进行JSON操作时忽略该属性。
      • @JsonFormat 此注解用于属性上,作用是把Data类型直接转化为想要的格式,如:@JsonFormat(pattern = “yyyy-MM-dd HH-mm-ss”)。

Validation模版引擎

注解

// Bean Validation 中内置的 constraint
@Null 被注释的元素必须为 null
@NotNull 被注释的元素必须不为 null
@AssertTrue 被注释的元素必须为 true
@AssertFalse 被注释的元素必须为 false
@Min(value) 被注释的元素必须是一个数字,其值必须大于等于指定的最小值
@Max(value) 被注释的元素必须是一个数字,其值必须小于等于指定的最大值
@DecimalMin(value) 被注释的元素必须是一个数字,其值必须大于等于指定的最小值
@DecimalMax(value) 被注释的元素必须是一个数字,其值必须小于等于指定的最大值
@Size(max=, min=) 被注释的元素的大小必须在指定的范围内
@Digits (integer, fraction) 被注释的元素必须是一个数字,其值必须在可接受的范围内
@Past 被注释的元素必须是一个过去的日期
@Future 被注释的元素必须是一个将来的日期
@Pattern(regex=,flag=) 被注释的元素必须符合指定的正则表达式

// Hibernate Validator 附加的 constraint
@NotBlank(message =) 验证字符串非null,且长度必须大于0
@Email 被注释的元素必须是电子邮箱地址
@Length(min=,max=) 被注释的字符串的大小必须在指定的范围内
@NotEmpty 被注释的字符串的必须非空
@Range(min=,max=,message=) 被注释的元素必须在合适的范围内

生成原理

/**
	 * 生成代码
	 */
	public void execute() {
		logger.debug("==========================准备生成文件...==========================");
		// 初始化配置
		initConfig();
		// 创建输出文件路径
		mkdirs(config.getPathInfo());
		// 获取上下文
		Map<String, VelocityContext> ctxData = analyzeData(config);
		// 循环生成文件
		for (Map.Entry<String, VelocityContext> ctx : ctxData.entrySet()) {
			batchOutput(ctx.getKey(), ctx.getValue());
		}
		// 打开输出目录
		if (config.getGlobalConfig().isOpen()) {
			try {
				String osName = System.getProperty("os.name");
				if (osName != null) {
					if (osName.contains("Mac")) {
						Runtime.getRuntime().exec("open " + config.getGlobalConfig().getOutputDir());
					} else if (osName.contains("Windows")) {
						Runtime.getRuntime().exec("cmd /c start " + config.getGlobalConfig().getOutputDir());
					} else {
						logger.debug("文件输出目录:" + config.getGlobalConfig().getOutputDir());
					}
				}
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		logger.debug("==========================文件生成完成!!!==========================");
	}
  1. 从mpg.execute()执行开始,根据执行方法一步步走
  2. 初始化配置
    • 方法:AbstractGenerator.initConfig()
    • 涉及初始化数据源DataSourceConfig,数据表StrategyConfig,包配置PackageConfig,模版TemplateConfig配置,全局信息GlobalConfig等属性。
    • 就是说你执行前的一些属性设置初始化,方便接下来的取值。
  3. 创建输出的文件夹
    • 方法:mkdirs(config.getPathInfo());
    • 就是创建你的java文件,jsp文件最终要输出的目录
  4. 获取上下文
    • 方法:analyzeData(ConfigBuilder config)
    • 根据全局配置取出controller,service等包名,超类的类名等变量
    • 循环表信息,为每个表设定controller类名,service类名、自定义属性等信息,为渲染vm模版数据准备
  5. 合成上下文模版
    • 根据表信息生成java文件和jsp文件
    • 将模版转化成为文件,使用velocity模版引擎合成数据与模版生成新的文件
  6. 打开输出目录

异常处理

spring异常处理

  • 实现方法 需要实现HandlerExceptionResolver这个接口类,并重写resolveException方法,在resolveExcepiton方法中处理自己的异常逻辑。
  • 全局处理器
    • /scan/ExceptionResolver.java
    • 继承HandlerEexceptionResolver并添加注解@Component交给spring处理
    • resolveExcetion方法里面需要做的事情
      • 使用log4j2记录异常,把异常信息记录到日志里面,方便查看日志找出问题
      • 判断方法是否是异步请求
      • 异步请求应该返回json数据并弹窗提示,同步请求返回到错误页面

Java web项目自带

<error-page>

        <error-code>404</error-code>

        <location>/WEB-INF/views/error/404.jsp</location>

    </error-page>

    <error-page>

        <error-code>500</error-code>

        <location>/WEB-INF/views/error/500.jsp</location>

    </error-page>

web项目的简单异常指引,一般来说有了异常处理之后可以不配这这个。

System.out.println()是指输出信息到控制台,不会记录到日志文件里面

在生成环境中,一般每天会生成一个日志文件,记录系统的运行信息

shiro权限控制

常用功能

帮助系统完成认证、授权、加密、会话管理、与web集成、缓存等。

  • Authentication:身份认证/登陆,验证永华是不是拥有相应的身份;
  • Authorization:授权,即权限验证,验证某个已认证的用户是否拥有某个权限;即判断用户是否能做事情,常见的如:验证某个用户是否拥有某个角色。或者细粒度的验证某个用户对某个资源是否具有某个权限;
  • Session Manager:会话管理,即用户登陆后就是一次会话,在没有退出之前,它的所有信息都在会话中;会话可以是普通javaSE环境的,也可以是如web环境的;
  • Caching:缓存,比如用户登陆后,其用户信息、拥有的角色/权限不必每次去查,这样可以提高效率;
  • Remember Me:记住我,这个是非常常见的功能,即一次登陆后,下次再来的话不用登陆了。

名词

  • Subject:主体,代表了当前“用户”
  • SecurityManager:安全管理器;即所有与安全有关的操作都会与SecurityManager交互;且它管理着所有Subject
  • Realm:域,Shiro从Realm获取安全数据(如用户、角色、权限)
  • SessionManager:管理主体与应用之间交互的数据
  • CacheManager:缓存控制器,来管理如用户、角色、权限等的缓存
  • Authrizer:授权器,或者访问控制器,用来决定主体是否有权限进行相应的操作
  • Authenticator:认证器,负责主体认证

shiro使用

从配置文件spring-shiro.xml看起,通过这个配置文件集成spring与shiro

<!-- Shiro Filter -->
    <bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
        <!-- 安全管理器 -->
        <property name="securityManager" ref="securityManager"/>
        <!-- 默认的登陆访问url -->
        <property name="loginUrl" value="/login"/>
        <!-- 登陆成功后跳转的url -->
        <property name="successUrl" value="/index"/>
        <!-- 没有权限跳转的url -->
        <property name="unauthorizedUrl" value="/unauth"/>
        <property name="filterChainDefinitions">
            <value>
                <!-- 
                    anon  不需要认证
                    authc 需要认证
                    user  验证通过或RememberMe登录的都可以
                -->
                /captcha.jpg = anon
                /commons/** = anon
                /static/** = anon
                /webhooks = anon
                /login = anon
                /** = user
            </value>
        </property>
    </bean>

过滤器(Shiro Filter) :是整个配置文件的入口,用于拦截需要安全控制的请求进行处理;属性主要包括url、登陆成功url、没权限url、不需要验证的url和安全管理器等

安全管理器(securityManager)
  • realm
    • 自定义ShiroDbRealm
      • 重写doGetAuthenticationInfo()方法:主要验证登陆密码是否正确,已经获取用户的权限和角色,交给shiro
      • 认证步骤:
        1. 用户提交用户名和密码
        2. shiro封装令牌(token,包含username和password信息)
        3. realm 通过用户名将密码查询返回
        4. shiro 自动去比较查询出密码和用户输入密码是否一致
        5. 进行登陆控制
      • matcher — RetryLimitCredentialsMatcher — 密码错误5次锁定
  • cacheManager:集成spring-cache作为shiro的缓存,项目中redis和ehcache用其中一个
  • rememberMeManager:记住登陆状态管理器
  • SessionManager — 会话管理器 — 主要配置登陆超时的session管理
注意:

Shiro不会去维护用户、维护权限;这些需要我们自己去设计/提供;然后通过相应的接口注入给shiro即可。

缓存机制

简介

缓存是介于应用程序和物理数据源之间,其作用是为了降低应用程序对物理数据源访问的频次,从而提高了应用的运行性能。

spring-cache

  • 它本质上不是一个具体的混存实现方案,而是一个对缓存使用的抽象
  • 通过在既有代码中添加少量它定义的各种annotation,即能够达到缓存方法的返回对象的效果
  • 特点:
    • 能够使用SpEL(Spring Expression Language)来定义缓存的key 和 各种 condition
    • 支持和主流的专业缓存,例如:EHCache、redis集成

注解形式:

 @Cacheable(value = "hour", key = "#id")
	public User selectById(Serializable id) {
		return userMapper.selectById(id);
	}

/impl/TestService.java

@Cacheable 缓存方法返回的值

编码形式:

@Autowired private CacheManager cacheManager;
	
	@Scheduled(cron = "0 5/20 * * * ?")
	public void cronTest() {
		// 测试手动存储cache
		Cache cache = cacheManager.getCache("hour");
		Integer xx = cache.get("x", new Callable<Integer>() {
			@Override
			public Integer call() throws Exception {
				return 111111;
			}
			
		});
		// 测试redis
//		redisTemplate.boundListOps("xxxx").leftPush("xxxx");
		
		// 测试注解
		testService.selectById(1L);
		testService.selectById(1L);
		testService.selectById(1L);
		
		logger.debug(xx);
		logger.debug(new Date());
	}

/task/TestTask.java

Cache cache = cacheManager.getCache(“hour”);

redis 和 ehcache 区别

ehcache:

  • 配置文件chcache.xml,配置缓存时间
  • 流行的纯Java开源缓存框架,配置简单、结构清晰、功能强大
  • 直接在jvm虚拟机中缓存,速度快,效率高
  • 但是缓存共享麻烦,集群分布式应用不方便

redis:

  • 通过socket访问到缓存服务
  • 效率比ecache低,比数据库要快很多
  • 处理集群和分布式缓存方便,有成熟的方案

spring-cache集成缓存

切换两种缓存:只需要注释其中一个即可

    <import resource="classpath:spring/spring-ehcache.xml"/>

    <!-- 

    <import resource="classpath:spring/spring-redis.xml"/>

     -->
使用建议

如果是单个应用或者缓存访问要求很高的应用,用ehcache。

如果是大型系统,存在缓存共享、分布式部署、缓存内容很大的,建议用redis。

Druid数据源监控

一个JDBC组件,包括3部分

  • DruidDriver代理Driver,能够提供基于Filter - Chain模式的插件体系
  • DruidDataSource 高效可管理的数据库连接池。
  • SQLParser

可以做什么

  1. 可以监控数据库访问性能,Druid内置提供了一个功能强大的StatFilter插件,能够详细统计SQL的执行性能,这对线上分析数据库访问性能有帮助
  2. 替换DBCP和C3P0.Druid提供了一个高效、波恩那个强大、可扩展性好的数据库连接池。
  3. SQL执行日志,Druid提供了不同的LogFilter,能够支持Common-Logging、Log4j和jdkLog,你可以按需求选择相应的LogFilter,监控你的应用数据库访问情况。
  4. 扩展JDBC,如果你要对JDBC层有编程需求,可以通过Druid提供的Filter-Chain机制,很方便编写JDBC扩展插件。

简单使用

spring-mabatis.xml 中使用Druid连接池作为数据源

<!-- base dataSource -->
    <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource" init-method="init" destroy-method="close">
        <property name="url" value="${db.master.url}" />
        <property name="username" value="${db.master.user}" />
        <property name="password" value="${db.master.password}" />
        
        <!-- 配置监控统计拦截的filters -->
        <property name="filters" value="mergeStat,wall,log4j2" />
        
        <property name="initialSize" value="5" />
        <property name="maxActive" value="100" />
        <property name="minIdle" value="10" />
        <property name="maxWait" value="60000" />
        <property name="validationQuery" value="SELECT 'x'" />
        <property name="testOnBorrow" value="true" />
        <property name="testOnReturn" value="true" />
        <property name="testWhileIdle" value="true" />
        <property name="timeBetweenEvictionRunsMillis" value="60000" />
        <property name="minEvictableIdleTimeMillis" value="300000" />
        <property name="removeAbandoned" value="true" />
        <property name="removeAbandonedTimeout" value="1800" />
        <property name="logAbandoned" value="true" />
    </bean>

在web.xml中配置Druid过滤器

<filter>
        <filter-name>DruidWebStatFilter</filter-name>
        <filter-class>com.alibaba.druid.support.http.WebStatFilter</filter-class>
        <init-param>
            <param-name>exclusions</param-name>
            <param-value>/static/*,*.ico,/druid/*</param-value>
        </init-param>
        <init-param>
            <param-name>sessionStatEnable</param-name>
            <param-value>false</param-value>
        </init-param>
    </filter>
    <filter-mapping>
        <filter-name>DruidWebStatFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>
    <!-- druid监控 -->
    <servlet>
        <servlet-name>DruidStatView</servlet-name>
        <servlet-class>com.alibaba.druid.support.http.StatViewServlet</servlet-class>
        <init-param>
            <param-name>loginUsername</param-name>
            <param-value>druid</param-value>
        </init-param>
        <init-param>
            <param-name>loginPassword</param-name>
            <param-value>druid</param-value>
        </init-param>
    </servlet>
    <servlet-mapping>
        <servlet-name>DruidStatView</servlet-name>
        <url-pattern>/druid/*</url-pattern>
    </servlet-mapping>

版权声明:本文由 Ian 在 2018年05月19日发表。本文采用CC BY-NC-SA 4.0许可协议,非商业转载请注明出处,不得用于商业目的。
文章题目及链接:《复习常用技术框架》




  相关文章:


留言区:

TOP