Spring学习笔记——AOP(4)
一、学习AOP
1.1 AOP的概述
1.2 AOP思想实现方案
1.3、模拟AOP的基础代码
1.4、AOP的相关概念
二、基于xml配置AOP
2.1 AOP基础入门
2.2、XML方式AOP配置详解
2.3、XML方式AOP原理剖析
三、注解式开发AOP
3.1 注解式开发AOP入门
3.2 AOP注解详细介绍
3.3、注解方式AOP原理解析
四、基于AOP的声明式事务控制
4.1 Spring事务编程概述
4.2 搭建测试环境
4.3 基于XML声明式事务控制
4.4 注解声明式事务控制
一、学习AOP
1.1 AOP的概述
AOP---->面向切面编程
是对面向对象编程OOP的升华。OOP是纵向对一个事物的抽象,一个对象包括静态的属性信息,包括动态的方法信息等。而AOP是横向的对不同事物的抽象,属性与属性
、方法与方法
、对象与对象
都可以组成一个切面,而用这种思维去设计编程的方式叫做面向切面编程
1.2 AOP思想实现方案
代理技术: 动态代理技术,在运行期间,对目标方法进行增强,代理对象同名方法内执行原有逻辑或方法的同时可以执行其他的增强逻辑,或者其他对象的方法
1.3、模拟AOP的基础代码
其实在之前学习BeanPostProcessor时,在BeanPostProcessor
的after方法
中使用动态代理对Bean进行了增强,实际存储到单例池singleObjects中的不是当前目标对象本身,而是当前目标对象的代理对象Proxy
,这样在调用目标对象方法时,实际调用的是代理对象Proxy的同名方法,起到了目标方法前后都进行增强的功能,对该方式进行一下优化,将增强的方法提取出去到一个增强类中,且只对com.itheima.service.impl
包下的任何类的任何方法进行增强
pubiic class MyAdvice {
public void beforeAdvice ( ) {
system. out. println ( "beforeAdvice..." ) ;
)
public void afterAdvice ( ) {
System . out. println ( "afterAdvice..." ) ;
}
}
public class MockAopBeanPostProcessor implements BeanPostProcessor , ApplicationContextAware {
private ApplicationContext applicationContext;
@Override
public Object postProcessAfterInitialization ( Object bean, String beanName) throws BeansException {
if ( bean. getClass ( ) . getPackage ( ) . getName ( ) . equals ( "com.Smulll.service.Impl" ) ) {
Object beanProxy = Proxy . newProxyInstance (
bean. getClass ( ) . getClassLoader ( ) ,
bean. getClass ( ) . getInterfaces ( ) ,
( Object proxy, Method method, Object [ ] args) -> {
Myadvice myadvice = applicationContext. getBean ( Myadvice . class ) ;
myadvice. before ( ) ;
Object invoke = method. invoke ( bean, args) ;
myadvice. after ( ) ;
return invoke;
} ) ;
return beanProxy;
}
return null ;
}
@Override
public void setApplicationContext ( ApplicationContext applicationContext) throws BeansException {
this . applicationContext = applicationContext;
}
}
1.4、AOP的相关概念
概念
单词
解释
目标对象
Target
被增强的方法所在的对象
代理对象
Proxy
对目标对象进行增强后的对象,客户端实际调用的对象
连接点
Joinpoint
目标对象中可以被增强的方法
切入点
Pointcut
目标对象中实际被增强的方法
通知\增强
Advice
增强部分的代码逻辑
切面
Aspect
增强和切入点的组合
织入
Weaving
将通知和切入点组合动态组合的过程
二、基于xml配置AOP
2.1 AOP基础入门
基本步骤:
导入AOP相关坐标;
< dependency>
< groupId> org.aspectjgroupId >
< artifactId> aspectjweaverartifactId >
< version> 1.9.6version >
dependency >
准备目标类、准备通知类,并配置给Spring管理;
配置切点表达式(哪些方法被增强);
配置织入(切点被哪些通知方法增强,是前置增强还是后置增强)。
< 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
http://www.springframework.org/schema/aop/spring-aop.xsd
" >
< bean id = " userService" class = " com.huanglei.service.Impl.UserServiceImpl" > bean >
< bean id = " myadvice" class = " com.huanglei.advice.Myadvice" > bean >
< aop: config>
< aop: pointcut id = " mtPointcut" expression = " execution(void com.Smulll.service.Impl.UserServiceImpl.show1())" />
< aop: aspect ref = " myadvice" >
< aop: before method = " before" pointcut-ref = " mtPointcut" > aop: before>
< aop: after method = " after" pointcut-ref = " mtPointcut" > aop: after>
aop: aspect>
aop: config>
beans >
2.2、XML方式AOP配置详解
xml配置AOP的方式还是比较简单的,下面看一下AOP详细配置的细节:
< ! -- 配置aop-- >
< aop: config>
< ! -- 配置切点表达式 目的:指定哪些方法被增强-- >
< aop: pointcut id= "mtPointcut" expression= "execution(void com.huanglei.service.Impl.UserServiceImpl.show1())" / >
< aop: pointcut id= "mtPointcut2" expression= "execution(void com.huanglei.service.Impl.UserServiceImpl.show2())" / >
< / aop: config>
pointcut属性可以再后面直接写上要结合的切点
< ! -- 配置aop-- >
< aop: config>
< ! -- 配置切点表达式 目的:指定哪些方法被增强-- >
< aop: pointcut id= "mtPointcut" expression= "execution(void com.huanglei.service.Impl.UserServiceImpl.show1())" / >
< ! -- 配置织入 目的:指定哪些切点与哪些通知结合-- >
< aop: aspect ref= "myadvice" >
< aop: before method= "before" pointcut- ref= "mtPointcut" > < / aop: before>
< aop: after method= "after" pointcut= "execution(void com.huanglei.service.Impl.UserServiceImpl.show1())" > < / aop: after>
< / aop: aspect>
< / aop: config>
切点表达式的配置语法
execution ( [ 访问修饰符] 返回值类型 包名. 类名. 方法名( 参数) )
详解:
访问修饰符可以省略不写;
返回值类型、某一级包名、类名、方法名可以使用*表示任意;
包名与类名之间使用单点.表示该包下的类,使用双点…表示该包及其子包下的类;
参数列表可以使用两个点…表示任意参数。
常见的切点表达式:
execution ( public void com. itheima. aop. TargetImpl. show ( ) )
execution ( * com. itheima. aop. TargetImpl. *( . . ) )
execution ( * com. itheima. aop. *. *( . . ) )
execution ( * com. itheima. aop. . *. *( . . ) )
execution ( * * . . *. *( . . ) )
通知名称
配置方式
执行时机
前置通知
目标方法执行之前执行
后置通知
目标方法执行之后执行,目标方法异常时,不在执行
环绕通知
目标方法执行前后执行,目标方法异常时,环绕后方法不在执行
异常通知
目标方法抛出异常时执行
最终通知
不管目标方法是否有异常,最终都会执行
通知方法再被调用时,Spring可以为其传递一些必要的参数
参数类型
作用
JoinPoint
连接点对象,任何通知都可使用,可以获得当前目标对象、目标方法参数等信息
ProceedingJoinPoint
JoinPoint子类对象,主要是在环绕通知中执行proceed(),进而执行目标方法
Throwable
异常对象,使用在异常通知中,需要在配置文件中指出异常对象名称
public void 通知方法名称( JoinPoint joinPoint) {
system. out. println ( joinPoint. getArgs ( ) ) ;
system. out. println ( joinPoint. getTarget ( ) ) ;
System . out. println ( joinPoint. getstaticPart ( ) ) ;
}
Throwable对象
public void afterThrowing ( JoinPoint joinPoint, Throwable th) {
System . out. println ( "异常对象是:" + th+ "异常信息是:" + th. getMessage ( ) ) ;
}
< aop: after- throwing method= "afterThrowing" pointcut- ref= "myPointcut" throwing= "th" / >
spring定义了一个Advice接口,实现了该接口的类都可以作为通知类出现
public interface Advice {
}
2.3、XML方式AOP原理剖析
动态代理的实现的选择,在调用getProxy()方法时,我们可选用的AopProxy接口有两个实现类,如上图,这两种都是动态生成代理对象的方式,一种就是基于JDK的,一种是基于Cglib的
代理技术
使用条件
配置方式
JDK动态代理技术
目标类有接口,是基于接口动态生成实现类的代理对象
目标类有接口的情况下,默认方式
Cglib 动态代理技术
目标类无接口且不能使用final修饰,是基于被代理对象动态生成子对象为代理对象
目标类无接口时,默认使用该方式;目标类有接口时,手动配置
Target target = new Target ( ) ;
Advices advices = new Advices ( ) ;
Enhancer enhancer = new Enhancer ( ) ;
enhancer. setSuperclass ( Target . class ) ;
enhancer. setCallback ( ( MethodInterceptor ) ( o, method, objects, methodProxy) -> {
advices. before ( ) ;
object result = method. invoke ( target, objects) ;
advices. afterReturning ( ) ;
return result;
} ) ;
Target tagetProxy = ( Target ) enhancer. create ( ) ;
String result = targetProxy. show ( "haohao" ) ;
三、注解式开发AOP
3.1 注解式开发AOP入门
Spring的AOP也提供了注解方式配置,使用相应的注解替代之前的xml配置,xml配置AOP时,我们主要配置了三部分:目标类被Spring容器管理、通知类被Spring管理、通知与切点的织入(切面),如下:
< bean id = " target" class = " com.itheima.aop.TargetImpl" > bean >
< bean id = " advices" class = " com.itheima.aop.Advices" > bean >
< aop: config proxy-target-class = " true" >
< aop: aspect ref = " advices" >
< aop: around method = " around" pointeut = " execution(* com.itheima.aop.*.*(..))" />
aop: aspect>
aop: config>
配置aop,其实配置aop主要就是配置通知类中的哪个方法(通知类型)对应的切点表达式是什么:
注解@Aspect、@Around需要被Spring解析,所以在Spring核心配置文件中需要在配置文件当中添加的自动代理
< aop: aspectj-autoproxy>
3.2 AOP注解详细介绍
通过不同的注解去完成各项通知类型:
@Before ( "execution( *com. itheima.aop.*.*(..))" )
public void before ( JoinPoint joinPoint) { }
@AfterReturning ( "execution(* com.itheima.aop.*.*(..))" )
public void afterReturning ( JoinPoint joinPoint) { }
@Around ( "execution (* com.itheima.aop.*.*(..))" )
public void around ( ProceedingJoinPoint joinPoint) throws Throwable { }
@AfterThrowing ( "execution(* com.itheima.aop.*.*(..))" )
public void afterThrowing ( JoinPoint joinPoint) { }
@After ( "execution(* com.itheima.aop.*.*(..))" )
public void after ( JoinPoint joinPoint) { }
3.3、注解方式AOP原理解析
之前在使用xml配置AOP时,是借助的Spring的外部命名空间的加载方式完成的,使用注解配置后,就抛弃了标签,而该标签最终加载了名为AspectJAwareAdvisorAutoProxyCreator的BeanPostProcessor ,最终,在该BeanPostProcessor中完成了代理对象的生成。
同样,从aspectj-autoproxy标签的解析器入手
this . registerBeanDefinitionParser ( "aspectj-autoproxy" , new AspectJAutoProxyBeanDefinitionParser ( ) ) ;
四、基于AOP的声明式事务控制
4.1 Spring事务编程概述
事务在开发的时候是必不可少的东西,在使用JDBC开发的时候,我们使用的是connection
对事物进行控制,使用Mybatis时,我们使用的时SqlSession对事物进行控制,缺点显而易见,我们在切换数据库访问技术的时候,事务控制的方式就会总是在改变,Spring就在这些技术的基础上,提供了统一的控制事务的接口。Spring的事务分为:编程式事务控制
和声明式事务控制
事务控制的方式
解释
编程式事务控制
Spring提供了事务控制的类和方法,使用编码的方式对业务代码进行了事务控制,事务控制的代码和业务操作代码耦合在一起,在开发当中很少使用
声明式事务控制
Spring提供了事务控制的封装,对外提供了xml配置和注解式开发的配置方式,可以通过配置的方式完成对事物的控制,可以达到事务控制和业务操作代码的解耦合,在开发当中推荐使用
Spring事务编程相关的类:
事务控制相关的类
解释
平台事务管理器 PlatformTransactionManager
是一个接口标准,实现类都具备事务提交、回滚和获得事务对象的功能,不同持久层框架可能会有不同实现方案
事务定义 TransactionDefinition
封装事务的隔离级别、传播行为、过期时间等属性信息
事务状态 TransactionStatus
存储当前事务的状态信息,如果事务是否提交、是否回滚、是否有回滚点等
虽然我们在开发当中不怎么使用这个编程式事务控制,但是对于这个编程式事务控制的相关类我们需要了解一下,因为我们在进行声明式配置的时候我们还会看见他们
4.2 搭建测试环境
搭建一个转账的环境,dao层一个转出钱的方法,一个转入钱的方法service层一个转账业务方法,内部分别调 用dao层转出钱和转入钱的方法,准备工作如下:
数据库准备一个账户表tb_account;
dao层准备一个AccountMapper,包括incrMoney和decrMoney两个方法;
service层准备一个transferMoney方法,分别调用incrMoney和decrMoney方法;
在applicationContext文件中进行Bean的管理配置;
测试正常转账与异常转账。
xml配置:
< beans xmlns = " http://www.springframework.org/schema/beans"
xmlns: xsi= " http://www.w3.org/2001/XMLSchema-instance"
xmlns: cotext= " http://www.springframework.org/schema/context"
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.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd
" >
< cotext: component-scan base-package = " com.huanglei" />
< cotext: property-placeholder location = " classpath:jdbc.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 class = " org.mybatis.spring.SqlSessionFactoryBean" >
< property name = " dataSource" ref = " dataSource" > property >
bean >
< bean class = " org.mybatis.spring.mapper.MapperScannerConfigurer" >
< property name = " basePackage" value = " com.huanglei.mapper" > property >
bean >
beans >
Mapper映射文件
public interface accountMapper {
@Update ( "update tb_account set money = money+#{money} where account_name = #{accountName}" )
public void incrMoney ( @Param ( "accountName" ) String accountName, @Param ( "money" ) Double money) ;
@Update ( "update tb_account set money = money-#{money} where account_name = #{accountName}" )
public void decrMoney ( @Param ( "accountName" ) String accountName, @Param ( "money" ) Double money) ;
}
service代码:
@Service ( "accountService" )
public class AccountServiceImpl implements AccountService {
@Autowired
private accountMapper accountMapper;
public void transferMoney ( String outAccount, String inAccount, Double money) {
accountMapper. decrMoney ( outAccount, money) ;
accountMapper. incrMoney ( inAccount, money) ;
}
}
4.3 基于XML声明式事务控制
结合我们学过的AOP技术,我们可以使用AOP对service的方法进行事务增强。
目标类:自定义的AccountServicelmpl,内部的方法是切点
通知类: Spring提供的,通知方法已经定义好,只需要配置即可
通知类是Spring提供的,需要导入Spring事务的相关的坐标;
配置目标类AccountServicelmpl;
使用advisor标签配置切面。
< beans xmlns = " http://www.springframework.org/schema/beans"
xmlns: xsi= " http://www.w3.org/2001/XMLSchema-instance"
xmlns: cotext= " http://www.springframework.org/schema/context"
xmlns: aop= " http://www.springframework.org/schema/aop"
xmlns: tx= " http://www.springframework.org/schema/tx"
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.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd
" >
< cotext: component-scan base-package = " com.huanglei" />
< cotext: property-placeholder location = " classpath:jdbc.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 class = " org.mybatis.spring.SqlSessionFactoryBean" >
< property name = " dataSource" ref = " dataSource" > property >
bean >
< bean class = " org.mybatis.spring.mapper.MapperScannerConfigurer" >
< property name = " basePackage" value = " com.huanglei.mapper" > property >
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 = " *" />
tx: attributes>
tx: advice>
< aop: config>
< aop: pointcut id = " txPointcut" expression = " execution(* com.Smulll.service.Impl.*.*(..))" />
< aop: advisor advice-ref = " txAdvice" pointcut-ref = " txPointcut" />
aop: config>
beans >
< tx: advice id = " txAdvice" transaction-manager = " transactionManager" >
< tx: attributes>
< tx: method name = " *" isolation = " READ_COMMITTED" propagation = " " timeout = " 3" read-only = " false" />
tx: attributes>
tx: advice>
**isolation属性:**指定了事务的隔离级别,事务并发存在三大问题:脏读,不可重复读,幻读/虚度
。可以通过设置事务的隔离级别来保证并发问题的实现,常用的是READ_COMMITTED和REPEATABLE_READ
常见的isolation设置:
isolation属性
解释
DEFAULT
表示的为默认的隔离级别,这个取决于你使用的哪种数据库,如MySQL就是REPEATABLE_READ
READ_UNCOMMITTED
A事务可以读取到B事务尚未提交的事务记录,不能解决任何并发问题,安全性最低,性能最高
READ_COMMITTED
A事务只能读取到其他事务已经提交的记录,不能读取到未提交的记录。可以解决脏读问题,但是不能解决不可重复读和幻读
REPEATABLE_READ
A事务多次从数据库读取某条记录结果一致,可以解决不可重复读,不可以解决幻读
SERIALIZABLE
串行化,可以解决任何并发问题,安全性最高,但是性能最低
**read-only属性:**就是设置当前的状态,为只读还是可以修改。设置为true表示只读,那么这样可以提高查询的性能,如果要增加或者删除修改,那必须得设置为法false
< tx: method name = " select*" read-only = " true" />
< tx: method name = " find*" read-only = " false" />
**timeout属性:**设置事务提交的最长时间,如果超过这个时间那么事务就会自动回滚,不再执行。默认值为-1,表示没有时间限制。
< tx: method name = " select*" read-only = " true" timeout = " 3" />
propagation属性 :设置事务的传播行为,主要解决是A方法调用B方法时,事务的传播方式问题的,例如:使用单方的事务,还是A和B都使用自己的事务等。事务的传播行为有如下七种属性值可配置
事务传播的行为
解释
REQUIRED (默认值)
A调用B,B需要事务,如果A有事务B就加入A的事务中,如果A没有事务,B就自己创建一个事务
REQUIRED_NEW
A调用B,B需要新事务,如果A有事务就挂起,B自己创建一个新的事务
SUPPORTS
A调用B,B有无事务无所谓,A有事务就加入到A事务中,A无事务B就以非事务方式执行
NOT_SUPPORTS
A调用B,B有无事务无所谓,A有事务就加入到A事务中,A无事务B就以非事务方式执行
NEVER
A调用B,B以无事务方式执行,A如有事务则抛出异常
MANDATORY
A调用B,B要加入A的事务中,如果A无事务就抛出异常
NESTED
A调用B, B创建一个新事务,A有事务就作为嵌套事务存在,A没事务就以创建的新事务执行
4.4 注解声明式事务控制
@Configuration
@ComponentScan ( "com.huanglei" )
@PropertySource ( "classpath:jdbc.properties" )
@MapperScan ( "com.huanglei.mapper" )
@EnableTransactionManagement
public class SpringConfig {
@Bean
public DataSource dataSource (
@Value ( "${jdbc.driver}" ) String driver,
@Value ( "${jdbc.url}" ) String url,
@Value ( "${jdbc.username}" ) String username,
@Value ( "${jdbc.password}" ) String password
) {
DruidDataSource dataSource = new DruidDataSource ( ) ;
dataSource. setDriverClassName ( driver) ;
dataSource. setUrl ( url) ;
dataSource. setUsername ( username) ;
dataSource. setPassword ( password) ;
return dataSource;
}
@Bean
public SqlSessionFactoryBean sqlSessionFactoryBean ( DataSource dataSource) {
SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean ( ) ;
sqlSessionFactoryBean. setDataSource ( dataSource) ;
return sqlSessionFactoryBean;
}
@Bean
public DataSourceTransactionManager transactionManager ( DataSource dataSource) {
DataSourceTransactionManager dataSourceTransactionManager = new DataSourceTransactionManager ( ) ;
dataSourceTransactionManager. setDataSource ( dataSource) ;
return dataSourceTransactionManager;
}
}
你可能感兴趣的:(Spring,spring,学习,笔记,后端)
【Python】一文详细介绍 py格式 文件
高斯小哥
Python基础【高质量合集】 python 新手入门 学习
【Python】一文详细介绍py格式文件个人主页:高斯小哥高质量专栏:Matplotlib之旅:零基础精通数据可视化、Python基础【高质量合集】、PyTorch零基础入门教程希望得到您的订阅和支持~创作高质量博文(平均质量分92+),分享更多关于深度学习、PyTorch、Python领域的优质内容!(希望得到您的关注~)文章目录一、py格式文件简介二、如何创建和编辑py格式文件三、如何运行py
大学播音主持都学什么内容?播音主持专业学什么?
配音新手圈
有些喜欢播音主持并且犹豫要不要报考这个大学专业的小伙伴们就会想要了解大学播音主持都学什么内容吧,毕竟如果不够了解就直接选择这个专业真的等选择完进去学习以后才知道这个专业并不是自己想要学习的东西那就来不及了。下面是小编为大家整理出来的一些播音主持专业学习的内容,请往下看吧。大学播音主持专业主要学习的课程有:播音发声、播音创作基础、广播播音主持、电视播音主持、文艺作品演播学概论、新闻学概论、新闻采编、
新网师的精神肤色(幕布笔记)
悦读书香
王子老师的《极简100小妙招》收到已经几天了,之前大概的浏览了全书,今天起给自己定了一个计划,必须每天学习极简小妙招里面的一个妙招,并加以运用。一、今天要打卡什么内容因有完成每天学习极简小妙招的计划,所以今天晚饭吃的比较简单,草草吃完以后带着小宝到广场溜达一圈,急忙赶回来学习极简小妙招。再重看的时候不知道自己要学点什么,打卡哪一招,感觉哪个都简单,就看这一环节像王子老师说的“一看就会”,但做这一环
学习JavaEE的日子 Day32 线程池
A 北枝
学习JavaEE 学习 java-ee java 线程池
Day32线程池1.引入一个线程完成一项任务所需时间为:创建线程时间-Time1线程中执行任务的时间-Time2销毁线程时间-Time32.为什么需要线程池(重要)线程池技术正是关注如何缩短或调整Time1和Time3的时间,从而提高程序的性能。项目中可以把Time1,T3分别安排在项目的启动和结束的时间段或者一些空闲的时间段线程池不仅调整Time1,Time3产生的时间段,而且它还显著减少了创建
SpringMVC设置全局异常处理器
水岸齐天
java spring
文章目录背景分析使用@ControllerAdvice(@RestControllerAdvice)+@ExceptionHandler实现全局异常全局异常处理-多个处理器匹配顺序存在一个类中存在不同的类中对于过滤器和拦截器中的异常,有两种思路可以考虑背景在项目中我们有需求做一个全局异常处理,来规范所有出去的异常信息。参考:官方文档分析首先ControllerAdvice(RestControll
没有如释重负
君远近
虽然只有短短的一个多月的努力复习时间,但今天的整个考试经过,还是发现了效果的,题目做的比较自如,没有慌里慌张,而且提前五分钟完成。至于考试成绩,没有实足的把握,60分都不敢保证。但绝对相信自己,比去年肯定要好!今天早早的赶到考场,见到了刘老师,谈起来学习情况,坦率的说,真的是自己不够重视。总以为会很难,没有信心。其实不是的,只要认真对待,树立足够的信心,绝对可以通过考试的。还向老师询问了,后续再报
C++学习笔记(lambda函数)
__TAT__
C&C++ c++ 学习 笔记
C++learningnote1、lambda函数的语法2、lambda函数的几种用法1、lambda函数的语法lambda函数的一般语法如下:[capture_clause](parameters)->return_type{function_body}capture_clause:需要捕获的变量,但要求该变量必须在这个作用域中。通常的捕获方式有以下几种:[]:不捕获任何变量[&]:按引用捕获变
使用多线程的方式模拟高并发请求接口,用于自测接口的稳定性【项目】
还算善良_
私有代码库 工具类 java list 数据结构
packagecom.gitee.taven.test;importcom.gitee.taven.ApiResult;importcom.gitee.taven.aop.RepeatSubmitAspect;importorg.slf4j.Logger;importorg.slf4j.LoggerFactory;importorg.springframework.beans.factory.an
心赏(2018.10.8)
六一节_3928
1.上班第一天,同事彤休完产假,回来上班,给我带了酸奶和水果。她生小孩时,我给她发了一个小红包贺喜,哪知她就记在心里了。心赏这个有心的90后。2.女儿放学回来,说自己当了小组长。一边说不想当,一边得意的样子。心赏老师给了孩子这个锻炼的机会。3.老妈今天做了"蚂蚁上树"的菜,得到女儿的高度肯定。心赏老妈还在不断学习。
springboot集成logback-spring.xml文件
RT_0114
SpringBoot spring boot spring logback
彩色日志日志分debug和error文件输出,方便开发人员运维日志限制最大保管天数日志限制总量大小占用量GB日志限制单个文件大小MB日志显示最大保留天数屏蔽没用的日志${CONSOLE_LOG_PATTERN}${log.path}/debug.log${log.path}/%d{yyyy-MM-dd,aux}/debug.%d{yyyy-MM-dd}.%i.log.gz1024MB50GB365
2022-2-13晨间日记
越亮也打烊
今天是什么日子起床:7:00就寝:12:08天气:晴心情:糟糕纪念日:无任务清单昨日完成的任务,最重要的三件事:寒假作业,网课,画画改进:作业时间剪短习惯养成:网课不逃~周目标·完成进度数学卷子100%学习·信息·阅读《傅雷家书》《钢铁是怎样炼成的》健康·饮食·锻炼我终于不喝饮料啦,喝茶~人际·家人·朋友邝姐姐带我吃火锅工作·思考啥时候开学,我还有几天赶完作业最美好的三件事1.卷子写完了2.我有冰
中原焦点团队38期王芳芳坚持分享第236天,20230630总约练134次,来访113次,咨8次,观察员13次
芳芳王
学习焦点的初心是想拯救孩子,孩子由于沉迷游戏,成绩下滑,在学习的过程中发现是自己的教育方式出了状况。经过半年的学习,一些焦点的基本技巧,如接纳、欣赏、倾听、同理心、尊重等都有了一定的了解。但在实际应用时仍然存在很多问题,感觉自己仍然没有放下对孩子成绩的期望,仍然把握不住对孩子管理的度。我该如何去陪伴好孩子?多用心去听课,并加强反思,多约练。去思考如何让自己快乐起来?
大创项目推荐 深度学习 opencv python 公式识别(图像识别 机器视觉)
laafeer
python
文章目录0前言1课题说明2效果展示3具体实现4关键代码实现5算法综合效果6最后0前言优质竞赛项目系列,今天要分享的是基于深度学习的数学公式识别算法实现该项目较为新颖,适合作为竞赛课题方向,学长非常推荐!学长这里给一个题目综合评分(每项满分5分)难度系数:3分工作量:4分创新点:4分更多资料,项目分享:https://gitee.com/dancheng-senior/postgraduate1课题
#D174-读书会作业-《财务自由之路》3
白洲笔记
最近沉迷于写作营,一直就没时间去弄读书会的作业,书的第二遍也就看了个开头,趁着日更的时间,赶紧把作业做了,这次是15到21课。【1.印象最深刻的部分】(本周所读内容中印象最深刻的部分)*活在未来,最正确的方法是什么?用正确的方法做正确的事情,判断什么是正确的?逻辑。学会思考。"作对事情"永远比“把事情作对“重要的多。”长远思考,耐心验证,小心总结提炼“证明自己正确并不是学习的任务和目标,时刻成长,
读书笔记《穿越寒冬》
如雪般飞舞
各位好,我们今天来讲一本书,名字叫作《穿越寒冬》。看起来特别应景,大家觉得现在创业的状况不景气,大家都在忍受着寒冬的煎熬。但实际上,这本书的英文名字并不是这个意思,它的英文名叫作“如何创立一家新公司,并且能够活下来”。我在整个读完了以后,我发现这本书真正要翻译得好,它的名字应该叫作《创业生存手册》。这个书的作者,来自硅谷的霍夫曼船长。霍夫曼船长写过一本让创业者觉得特别贴心的书,叫作《让大象飞》它和
账务处理又出错?资深会计来教你,学会效率翻倍!共同学习
小橘子要努力吖
作为一名会计,在实际工作中会遇到各种麻烦的账务处理问题。那么,最常用的会计处理方法都有哪些呢?今天小编为大家带来了从业二十六年的资深老会计分享的十四中会计常用的账务处理问题的解决方案,快来看看吧!一、促销品的账务处理在促销时公司经常会把一些商品按进价赠送给消费者使用二、款已付清但发票未到的账务处理三、购买材料发生不合理损耗的账务处理问题公司在购买材料时,常常会发生一些不合理的损耗,那么这种问题该怎
【真诚子】通晓鬼谷第七篇读书日记。
真诚子l通晓鬼谷
今天把个人品牌,从193读到208页,书的内容质量出奇的高,尤其是这一段。对标学习法,找一个比自己强,或者你期望成为的人进行模仿性学习,对标学习,不是到处,去找人对标兵学习很多人的优点,或是学习自己认为好的方面,而是找准一个对标高手,然后全方位的学习这个人。我在做品牌咨询时就对标,学习了一个在国内很有名的行业顶尖大咖。我先找到他公司的方案,进行完全模仿,连PPT的排版都一样,而且我只参照他一个人的
ES-LTR粗排模块
poins
jenkins 运维
ES-LTR粗排模块官方资源:https://github.com/HeiBoWang/elasticsearch-learning-to-rankElasticsearch学习排名插件使用机器学习提高搜索相关性排名。它为维基媒体基金会和Snagajob等地方的搜索提供了动力!这个插件有什么功能此插件:允许您在Elasticsearch中存储特征(Elasticsearch查询模板)记录特征得分(
2018-11-18成长小组学习笔记
实验中学45
因为嗓子“罢工”,我面对众人只能借“微笑”代言。在开始授课前,绣霞老师先反馈上次作业的情况,提到“接纳”需是真正发自内心的完全接纳,而不是口头上的接纳,内心却是排斥的。提到一个“问题”孩子恰恰对家爱的更加“深沉”,夫妻间的问题不能影响到孩子,对孩子更好的爱不是你为他做的更多,而是给他自由、健康成长的空间。图片发自App一、孩子:家庭的一面镜子夫妻成了彼此的“投射”,婚姻便“吵的不可开交”,婚姻便成
eclipse导入项目 warning报错 org.springframework.ide.eclipse.core.springnature
zhangfeng1133
ide eclipse java
报错org.springframework.ide.eclipse.core.springnature报错信息"org.springframework.ide.eclipse.core.springnature"通常表示EclipseIDE中与Spring框架集成的插件出现了问题。这个错误可能是因为SpringIDE插件没有正确安装或配置,或者Eclipse的更新过程中出现了问题。解决方法:确认S
【鸿蒙HarmonyOS开发笔记】ArkUI常用组件介绍汇总(更新中)
温、
鸿蒙HarmonyOS开发笔记 学习记录 harmonyos 笔记 华为
概述此文总结开发中用到的一些常用组件,便于查阅,此文持续更新,闲的没事就更线性布局(Row/Column)不多介绍了,最常用的布局组件,两者除了方向不一样,别的都一样方便起见下面只写Column常用属性排列方向上的间距:spaceColumn({space:20}){Row().width('90%').height(50).backgroundColor(0xF5DEB3)Row().width
2019-07-16
振华老凤祥店长崔宁宁
大爱的李老师,智慧的教授,亲爱的跃友们:大家好!我是莱州鑫和金店李总的人~崔宁宁今天是我的日精进行动第56天,我分享一下今天的改变,我们相互勉励,每天进步一点点,离成功便不远。1、比学习:人这一生最主要的就是信念,坚定不移的信念是成功路上的重要基石!2、比改变:我是一切的根源,我变了世界就变了!改变自己的心态!3、比付出:承担才能成长,付出才会杰出!4、比谦卑:学习每位优秀店长身上的优点!5、比感
python清华大学出版社答案_Python机器学习及实践
weixin_39805119
python清华大学出版社答案
第1章机器学习的基础知识1.1何谓机器学习1.1.1传感器和海量数据1.1.2机器学习的重要性1.1.3机器学习的表现1.1.4机器学习的主要任务1.1.5选择合适的算法1.1.6机器学习程序的步骤1.2综合分类1.3推荐系统和深度学习1.3.1推荐系统1.3.2深度学习1.4何为Python1.4.1使用Python软件的由来1.4.2为什么使用Python1.4.3Python设计定位1.4.
2018-12-02
子分小
姓名:张颖公司:菲尔德国际英语【反省总结第146天,始于20180709今天是20181202】【知~学习】六项精进大纲背诵3遍每天十个单词坚持第181天每天学习一篇英文文章第94天英语流利说课程第71天学习30分钟【行~实践】一、修身:(对自己个人)步行5000步二、齐家:(对家庭和家人)无三、建功:(对工作)完成与Arti活动课和两节Demo准备开班事宜{积善}:发愿从2018年7月9日起1年
安卓笔记本 - Handler Message MessageQueue Looper
SocialException
不爱写字,一张图解决。Handler,Message,MessageQueue,Looper工作原理
枚举使用笔记
万变不离其宗_8
项目笔记 笔记
1.java枚举怎么放在方法上面的注释里面/***保存*@paramuserId用户id*@paramtype见枚举{@linkcom.common.enums.TypeEnum}*@return*/voidsave(LonguserId,Stringtype);
如何成为思维的高手?
明安包装闫慧玲
六项精进训练营Day2复盘20210112湖北荆州学习靠氛围,成长靠圈子1.关于金钱认知金句:1.当今世界,非钱不行2.有钱能使鬼推磨3.金钱是万恶之本4.时间就是金钱5.金钱不是万能的,但是没有钱是万万不能的6.谈钱伤感情,谈感情伤钱道德系统→好人→美德→回流利益系统→好好生活天下熙熙皆为利来,天下攘攘皆为利往出自西汉著名史学家、文学家司马迁《史记》的第一百二十九章“货殖列传”。这句话意思是说天
十分钟自由写作
知意zy
主题:我缺乏的东西自从加入2022年弘丹写作学院,感觉每天的生活都忙碌了起来,我要上班,要学习。所以我每天都必须拼尽全力向前奔跑,才追得上小伙伴们的脚步。在写作学院,我学会了反省自己的不足,我的想法多,缺乏的东西也太多。比如:写作的文笔,写作逻辑,底层自信心……看到社群里那么多优秀的小伙伴,我感觉自己越来越自卑,我这么一个平庸的人,会完成今年的写作目标吗?我开始不停怀疑自己是否能坚持下去。而弘丹老
2021-04-11
英英成长日记
(1)每天写50字以上的催眠语言肯定自己或孩子或爱人今天的公益沙龙第二期,你有充分的准备!所以一切都很顺利!你还可以更灵活,我相信你可以做到!你是一个有爱的人!爱能成就一切!加油!分享也是成长!你说对吗?(2)每天晚上跟潜意识沟通一次。谢谢你潜意识,今天支持我讲完两个小时沙龙!感恩你每天这样支持我成长学习!(3)每天学习三条时间管理方法,共100条。(4)自己想要坚持3件事(确定下来至少一件,坚持
ruoyi使用笔记
万变不离其宗_8
项目笔记 代码参考笔记 笔记 java 前端
1.限流处理@RateLimiter@PostMapping("/createOrder")@ApiOperation("创建充值订单")@RateLimiter(key=CacheConstants.REPEAT_SUBMIT_KEY,time=10,count=1,limitType=LimitType.IP)publicRcreateOrder(@RequestBodyFormform){/
解读Servlet原理篇二---GenericServlet与HttpServlet
周凡杨
java HttpServlet 源理 GenericService 源码
在上一篇《解读Servlet原理篇一》中提到,要实现javax.servlet.Servlet接口(即写自己的Servlet应用),你可以写一个继承自javax.servlet.GenericServletr的generic Servlet ,也可以写一个继承自java.servlet.http.HttpServlet的HTTP Servlet(这就是为什么我们自定义的Servlet通常是exte
MySQL性能优化
bijian1013
数据库 mysql
性能优化是通过某些有效的方法来提高MySQL的运行速度,减少占用的磁盘空间。性能优化包含很多方面,例如优化查询速度,优化更新速度和优化MySQL服务器等。本文介绍方法的主要有:
a.优化查询
b.优化数据库结构
ThreadPool定时重试
dai_lm
java ThreadPool thread timer timertask
项目需要当某事件触发时,执行http请求任务,失败时需要有重试机制,并根据失败次数的增加,重试间隔也相应增加,任务可能并发。
由于是耗时任务,首先考虑的就是用线程来实现,并且为了节约资源,因而选择线程池。
为了解决不定间隔的重试,选择Timer和TimerTask来完成
package threadpool;
public class ThreadPoolTest {
Oracle 查看数据库的连接情况
周凡杨
sql oracle 连接
首先要说的是,不同版本数据库提供的系统表会有不同,你可以根据数据字典查看该版本数据库所提供的表。
select * from dict where table_name like '%SESSION%';
就可以查出一些表,然后根据这些表就可以获得会话信息
select sid,serial#,status,username,schemaname,osuser,terminal,ma
类的继承
朱辉辉33
java
类的继承可以提高代码的重用行,减少冗余代码;还能提高代码的扩展性。Java继承的关键字是extends
格式:public class 类名(子类)extends 类名(父类){ }
子类可以继承到父类所有的属性和普通方法,但不能继承构造方法。且子类可以直接使用父类的public和
protected属性,但要使用private属性仍需通过调用。
子类的方法可以重写,但必须和父类的返回值类
android 悬浮窗特效
肆无忌惮_
android
最近在开发项目的时候需要做一个悬浮层的动画,类似于支付宝掉钱动画。但是区别在于,需求是浮出一个窗口,之后边缩放边位移至屏幕右下角标签处。效果图如下:
一开始考虑用自定义View来做。后来发现开线程让其移动很卡,ListView+动画也没法精确定位到目标点。
后来想利用Dialog的dismiss动画来完成。
自定义一个Dialog后,在styl
hadoop伪分布式搭建
林鹤霄
hadoop
要修改4个文件 1: vim hadoop-env.sh 第九行 2: vim core-site.xml <configuration> &n
gdb调试命令
aigo
gdb
原文:http://blog.csdn.net/hanchaoman/article/details/5517362
一、GDB常用命令简介
r run 运行.程序还没有运行前使用 c cuntinue 
Socket编程的HelloWorld实例
alleni123
socket
public class Client
{
public static void main(String[] args)
{
Client c=new Client();
c.receiveMessage();
}
public void receiveMessage(){
Socket s=null;
BufferedRea
线程同步和异步
百合不是茶
线程同步 异步
多线程和同步 : 如进程、线程同步,可理解为进程或线程A和B一块配合,A执行到一定程度时要依靠B的某个结果,于是停下来,示意B运行;B依言执行,再将结果给A;A再继续操作。 所谓同步,就是在发出一个功能调用时,在没有得到结果之前,该调用就不返回,同时其它线程也不能调用这个方法
多线程和异步:多线程可以做不同的事情,涉及到线程通知
&
JSP中文乱码分析
bijian1013
java jsp 中文乱码
在JSP的开发过程中,经常出现中文乱码的问题。
首先了解一下Java中文问题的由来:
Java的内核和class文件是基于unicode的,这使Java程序具有良好的跨平台性,但也带来了一些中文乱码问题的麻烦。原因主要有两方面,
js实现页面跳转重定向的几种方式
bijian1013
JavaScript 重定向
js实现页面跳转重定向有如下几种方式:
一.window.location.href
<script language="javascript"type="text/javascript">
window.location.href="http://www.baidu.c
【Struts2三】Struts2 Action转发类型
bit1129
struts2
在【Struts2一】 Struts Hello World http://bit1129.iteye.com/blog/2109365中配置了一个简单的Action,配置如下
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configurat
【HBase十一】Java API操作HBase
bit1129
hbase
Admin类的主要方法注释:
1. 创建表
/**
* Creates a new table. Synchronous operation.
*
* @param desc table descriptor for table
* @throws IllegalArgumentException if the table name is res
nginx gzip
ronin47
nginx gzip
Nginx GZip 压缩
Nginx GZip 模块文档详见:http://wiki.nginx.org/HttpGzipModule
常用配置片段如下:
gzip on; gzip_comp_level 2; # 压缩比例,比例越大,压缩时间越长。默认是1 gzip_types text/css text/javascript; # 哪些文件可以被压缩 gzip_disable &q
java-7.微软亚院之编程判断俩个链表是否相交 给出俩个单向链表的头指针,比如 h1 , h2 ,判断这俩个链表是否相交
bylijinnan
java
public class LinkListTest {
/**
* we deal with two main missions:
*
* A.
* 1.we create two joined-List(both have no loop)
* 2.whether list1 and list2 join
* 3.print the join
Spring源码学习-JdbcTemplate batchUpdate批量操作
bylijinnan
java spring
Spring JdbcTemplate的batch操作最后还是利用了JDBC提供的方法,Spring只是做了一下改造和封装
JDBC的batch操作:
String sql = "INSERT INTO CUSTOMER " +
"(CUST_ID, NAME, AGE) VALUES (?, ?, ?)";
[JWFD开源工作流]大规模拓扑矩阵存储结构最新进展
comsci
工作流
生成和创建类已经完成,构造一个100万个元素的矩阵模型,存储空间只有11M大,请大家参考我在博客园上面的文档"构造下一代工作流存储结构的尝试",更加相信的设计和代码将陆续推出.........
竞争对手的能力也很强.......,我相信..你们一定能够先于我们推出大规模拓扑扫描和分析系统的....
base64编码和url编码
cuityang
base64 url
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.io.UnsupportedEncodingException;
web应用集群Session保持
dalan_123
session
关于使用 memcached 或redis 存储 session ,以及使用 terracotta 服务器共享。建议使用 redis,不仅仅因为它可以将缓存的内容持久化,还因为它支持的单个对象比较大,而且数据类型丰富,不只是缓存 session,还可以做其他用途,一举几得啊。1、使用 filter 方法存储这种方法比较推荐,因为它的服务器使用范围比较多,不仅限于tomcat ,而且实现的原理比较简
Yii 框架里数据库操作详解-[增加、查询、更新、删除的方法 'AR模式']
dcj3sjt126com
数据库
public function getMinLimit () { $sql = "..."; $result = yii::app()->db->createCo
solr StatsComponent(聚合统计)
eksliang
solr聚合查询 solr stats
StatsComponent
转载请出自出处:http://eksliang.iteye.com/blog/2169134
http://eksliang.iteye.com/ 一、概述
Solr可以利用StatsComponent 实现数据库的聚合统计查询,也就是min、max、avg、count、sum的功能
二、参数
百度一道面试题
greemranqq
位运算 百度面试 寻找奇数算法 bitmap 算法
那天看朋友提了一个百度面试的题目:怎么找出{1,1,2,3,3,4,4,4,5,5,5,5} 找出出现次数为奇数的数字.
我这里复制的是原话,当然顺序是不一定的,很多拿到题目第一反应就是用map,当然可以解决,但是效率不高。
还有人觉得应该用算法xxx,我是没想到用啥算法好...!
还有觉得应该先排序...
还有觉
Spring之在开发中使用SpringJDBC
ihuning
spring
在实际开发中使用SpringJDBC有两种方式:
1. 在Dao中添加属性JdbcTemplate并用Spring注入;
JdbcTemplate类被设计成为线程安全的,所以可以在IOC 容器中声明它的单个实例,并将这个实例注入到所有的 DAO 实例中。JdbcTemplate也利用了Java 1.5 的特定(自动装箱,泛型,可变长度
JSON API 1.0 核心开发者自述 | 你所不知道的那些技术细节
justjavac
json
2013年5月,Yehuda Katz 完成了JSON API(英文,中文) 技术规范的初稿。事情就发生在 RailsConf 之后,在那次会议上他和 Steve Klabnik 就 JSON 雏形的技术细节相聊甚欢。在沟通单一 Rails 服务器库—— ActiveModel::Serializers 和单一 JavaScript 客户端库——&
网站项目建设流程概述
macroli
工作
一.概念
网站项目管理就是根据特定的规范、在预算范围内、按时完成的网站开发任务。
二.需求分析
项目立项
我们接到客户的业务咨询,经过双方不断的接洽和了解,并通过基本的可行性讨论够,初步达成制作协议,这时就需要将项目立项。较好的做法是成立一个专门的项目小组,小组成员包括:项目经理,网页设计,程序员,测试员,编辑/文档等必须人员。项目实行项目经理制。
客户的需求说明书
第一步是需
AngularJs 三目运算 表达式判断
qiaolevip
每天进步一点点 学习永无止境 众观千象 AngularJS
事件回顾:由于需要修改同一个模板,里面包含2个不同的内容,第一个里面使用的时间差和第二个里面名称不一样,其他过滤器,内容都大同小异。希望杜绝If这样比较傻的来判断if-show or not,继续追究其源码。
var b = "{{",
a = "}}";
this.startSymbol = function(a) {
Spark算子:统计RDD分区中的元素及数量
superlxw1234
spark spark算子 Spark RDD分区元素
关键字:Spark算子、Spark RDD分区、Spark RDD分区元素数量
Spark RDD是被分区的,在生成RDD时候,一般可以指定分区的数量,如果不指定分区数量,当RDD从集合创建时候,则默认为该程序所分配到的资源的CPU核数,如果是从HDFS文件创建,默认为文件的Block数。
可以利用RDD的mapPartitionsWithInd
Spring 3.2.x将于2016年12月31日停止支持
wiselyman
Spring 3
Spring 团队公布在2016年12月31日停止对Spring Framework 3.2.x(包含tomcat 6.x)的支持。在此之前spring团队将持续发布3.2.x的维护版本。
请大家及时准备及时升级到Spring
fis纯前端解决方案fis-pure
zccst
JavaScript
作者:zccst
FIS通过插件扩展可以完美的支持模块化的前端开发方案,我们通过FIS的二次封装能力,封装了一个功能完备的纯前端模块化方案pure。
1,fis-pure的安装
$ fis install -g fis-pure
$ pure -v
0.1.4
2,下载demo到本地
git clone https://github.com/hefangshi/f