Spring bean的生命周期

当我们写一个很小的项目的时候,如果需要创建对象,那么很可能用new出来一个对象就行了。当项目越来越大的时候,对象的管理、对象之间的依赖关系、对象的生命周期管理就会变得越来越复杂。 如果可以不需要由来创建对象、管理对象的依赖关系、管理对象的生命周期的话,那就太好了。Spring框架就可以提供上述的功能,大大地提高了开发者的开发效率。 首先说一下对象创建,除了用new来创建一个对象之外,还可以使用反射来创建。(可以见我关于java反射的笔记)比如说,利用反射,只需要知道类名,就可以生成类的实例。以下示例代码就生成了一个MyService的实例。 Class<?> clazz = Class.forName("site.nemo.learn.reflect.MyService"); Object obj = clazz.newInstance(); 既然可以用反射来创建实例,那么我只需要提供类名,框架就可以帮我来创建实例。那么我可以把我需要创建示例的类名都列在一个文件里面,框架只需要去读这个文件就可以了。 很早的时候,即还没有引入注解的时候,Spring框架是可以从xml文件里面生成对象实例的。 我们来举个例子。 新建一个maven项目,引入以下依赖:…

Spring事务:@Transactional注解在什么情况下不生效

这篇笔记来学习一下使用Spring框架的时候,@Transactional注解标注的方法在什么情况下事务不会生效。 我们可以写一个demo项目, 引入以下依赖 <dependencies> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>5.1.6</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>…

Spring原理:如何实现模块装配

在我们使用springboot编码的过程中,会遇见使用@EnableXXX开启某个模块的情况。比如说@EnableAsync开启异步,@EnableCache开启缓存…… 这篇笔记来学习,如何自定义一个@EnableXXX注解,当这个注解被使用的时候,模块就自动装配了。 假设,我们自己定义了一个美颜模块,希望当启动类标上@EnableBeauty注解的时候,能够开启美颜模块。 我们可以设想,美颜功能包括:瘦脸、美白、大眼…… 我们可以新建一个maven项目,引入以下依赖 <dependencies> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>5.2.8.…

Spring事务传播行为

这篇笔记里面来学习一下Spring的事务的传播行为 首先看下有哪几种传播 REQUIRED表示如果当前有事务,就加入该事务。如果当前没事务,就新起一个事务 SUPPORTS表示如果当前有事务,就加入该事务。如果当前没事务,则以非事务运行 MANDATORY表示如果当前有事务,就加入该事务。如果当前没事务,则报错 REQUIRES_NEW表示如果当前有事务,则当前事务被挂起,并新起一个事务。如果当前没事务,新起一个事务 NOT_SUPPORTED表示不管当前是否有事务,则以非事务运行,如果当前有事务则当前事务会被挂起 NEVER表示不支持事务。如果当前有事务,则报错 NESTED表示如果当前有事务,则会在嵌套事务中运行。嵌套的事务可以独立于当前事务进行单独提交或回滚。如果当前没事务,则新起一个事务。 同一个类NemoService里面的A和B两个方法,假如说A的事务传播行为是REQUIRED,B的事务传播行为是REQUIRES_NEW,A内部调用了B。当我们在外面使用@Autowire获得了NemoService的bean nemoService,并且调用nemoService.A()的时候,其实B并没有新起一个事务。这是由于Spring AOP的底层原理是动态代理,由于A内部调用了B,所以B是没有被增强过的即@Transactional不起作用。…

Java unchecked异常

这篇笔记来学习一下java里面的异常。 java里所有的异常都继承自Throwable。下面简单列了一下常见的几种异常 将派生于Error或者RuntimeException的异常称为unchecked异常,所有其他的异常成为checked异常 需要注意的是,常见的ClassNotFoundException并不是派生于RuntimeException,所以它不是unchecked异常。 为什么要对unchecked异常和checked异常进行区分? 主要是编译器在编译期间会检查开发者是否为所有的checked异常提供了异常处理机制…

Java 反射

Java反射是指在运行时能够获取一个类的全部信息。 比如说有一个类MyService public class MyService { private String nameA; public String nameB; public MyService() { this.nameA = null; this.nameB = null; } public MyService(String nameA, String nameB) { this.nameA = nameA; this.nameB = nameB; } private void funcA() { } public void funcB() { } protected void funcC() { } public String funcD(int param1, String param2, Boolean param3) { return…

如何更好地使用mysql索引

这篇笔记主要是记录一下mysql索引在实际应用中的一些注意点。 1.建议使用自增id作为表的主键 在之前关于innodb行格式的学习中,已经知道了数据页里面的数据是按主键递增的顺序串起来的。 如果我们建表的时候,没有使用自增列作为主键,而是使用了业务相关的列作为主键,那么在业务上会有很多插入、删除操作。如果一个数据页已经满了,此时再在中间插入一条记录的话,就需要分页。相对应的就是,如果删除了大量数据,一个页里面的数据太少的话,也会进行页的合并。页分裂和页合并都是开销很大的操作,我们需要避免。 所以,我们在实际应用中,建议使用自增id作为主键,而不是业务上的某个属性作为主键。 2.在业务中使用查询语句的时候不要select *,建议写明需要的列名 在上一篇笔记为什么innodb索引采用B+树结构里面,已经学习过索引的结构。已经知道叶子节点存放的是具体的数据,非叶子节点是索引。 那么innodb索引的结构可以简化成如下图所示: 在innodb里面,主键索引又叫聚簇索引。 我们在实际应用中,除了主键索引,还会在某个列上面建立索引,例如 CREATE TABLE `testsecondaryindex` ( `c1` int(10) unsigned NOT NULL AUTO_INCREMENT, `c2`…

mysql-innodb更新varchar字段值时存储的变化

这篇笔记是innodb行格式这一篇的后续,主要是想看一下varchar类型的字段更新的时候数据页的变化。 首先还是建立一个与innodb行格式这篇笔记一样的表,只不过我改了一下表名。 CREATE TABLE `testupdate` ( `c1` int(10) unsigned NOT NULL AUTO_INCREMENT, `c2` varchar(255) DEFAULT NULL, `c3` char(11) DEFAULT NULL, `c4` varchar(255) DEFAULT NULL, PRIMARY KEY (`c1`) ) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=ascii ROW_FORMAT=COMPACT 往里面插入了一样的数据。那么我们可以设想,将testupdate.ibd转成十六进制来查看的时候,也可以在0xC080找到第一行的内容,可以在0xC0C1找到第三行的内容,…