一句话概括:

Spring是一个轻量级的控制反转(IoC)和面向切面(AOP)的容器(框架)。

组成

  • 核心容器:核心容器提供 Spring 框架的基本功能。核心容器的主要组件是 BeanFactory,它是工厂模式的实现。

    BeanFactory 使用控制反转(IOC) 模式将应用程序的配置和依赖性规范与实际的应用程序代码分开。

  • Spring 上下文: 简单理解就是spring的当前运行的环境,也可以理解是spring可以利用的资源。

  • Spring AOP:面向切面的编程功能 ,提供了事务管理服务。

    通过使用 Spring AOP,不用依赖组件,就可以将声明性事务管理集成到应用程序中。

  • Spring DAO:Spring DAO 的面向 JDBC 的异常遵从通用的 DAO 异常层次结构。

  • Spring ORM: 对象关系映射(Object Relational Mapping) 。

    用于实现面向对象编程语言里不同类型系统的数据之间的转换

  • Spring Web 模块:Web 上下文模块建立在应用程序上下文模块之上,为基于 Web 的应用程序提供了上下文。

  • Spring MVC 框架:MVC 框架是一个全功能的构建 Web 应用程序的 MVC 实现。通过策略接口,MVC 框架变成为高度可配置的,MVC 容纳了大量视图技术,其中包括 JSP、Velocity、Tiles、iText 和 POI。

Spring Boot与Spring Cloud

  • Spring Boot 是 Spring 的一套快速配置脚手架,可以基于Spring Boot 快速开发单个微服务。
  • Spring Cloud是基于Spring Boot实现的。
  • Spring Boot专注于快速、方便集成的单个微服务个体,Spring Cloud关注全局的服务治理框架。
  • Spring Boot使用了约束优于配置的理念,很多集成方案已经帮你选择好了,能不配置就不配置 , Spring Cloud很大的一部分是基于Spring Boot来实现,Spring Boot可以离开Spring Cloud独立使用开发项目,但是Spring Cloud离不开Spring Boot,属于依赖的关系。
  • SpringBoot在SpringClound中起到了承上启下的作用。

IOC

控制反转IoC(Inversion of Control),是一种设计思想,DI是实现IOC的一种方法

  • 控制 : 谁来控制对象的创建 , 传统应用程序的对象是由程序本身控制创建的 , 使用Spring后 , 对象是由Spring来创建的
  • 反转 : 程序本身不创建对象 , 而变成被动的接收对象 .

依赖注入(Dependency Injection,DI) : 就是利用set方法来进行注入的。

IOC是一种编程思想,由主动的编程变成被动的接收

一句话 : 对象由Spring 来创建 , 管理 , 装配 !

以前设计一段代码:

//先写一个UserDao接口
public interface UserDao {
public void getUser();
} //再去写Dao的实现类
public class UserDaoImpl implements UserDao {
@Override
public void getUser() {
System.out.println("获取用户数据");
}
} //然后去写UserService的接口
public interface UserService {
public void getUser();
} //最后写Service的实现类
public class UserServiceImpl implements UserService {
private UserDao userDao = new UserDaoImpl(); @Override
public void getUser() {
userDao.getUser();
}
}

实现类 +++++++ 的时候

都需要修改大量代码 ,这种设计的耦合性太高了,牵一发而动全身 。

我们可以在需要用到他的地方 , 不去实现它 , 而是留出一个接口 , 利用set , 我们去代码里修改下 。

public class UserServiceImpl implements UserService {
private UserDao userDao;
// 利用set实现
public void setUserDao(UserDao userDao) {
this.userDao = userDao;
} @Override
public void getUser() {
userDao.getUser();
}
}

以前所有东西都是由程序去进行控制创建 , 而现在是由我们自行控制创建对象 。

程序不用去管怎么创建,怎么实现了 ,它只负责提供一个接口 。

DI

  • 依赖注入(Dependency Injection,DI)。
  • 依赖 : 指Bean对象的创建依赖于容器 , Bean对象的依赖资源 。
  • 注入 : 指Bean对象所依赖的资源 ,由容器来设置和装配 。

1、常量注入

<bean id="student" class="com.zwt.pojo.Student">
<property name="name" value="小明"/>
</bean> @Test
public void test01(){
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml"); Student student = (Student) context.getBean("student"); System.out.println(student.getName()); }

2、Bean注入

注意点:这里的值是一个引用,ref。

 <bean id="addr" class="com.zwt.pojo.Address">
<property name="address" value="重庆"/>
</bean> <bean id="student" class="com.zwt.pojo.Student">
<property name="name" value="小明"/>
<property name="address" ref="addr"/>
</bean>

3、Properties注入

<property name="info">
<props>
<prop key="学号">20190604</prop>
<prop key="性别">男</prop>
<prop key="姓名">小明</prop>
</props>
</property>

…………

p命名和c命名注入

1、P命名空间注入 : 需要在头文件中加入约束文件

导入约束 : xmlns:p="http://www.springframework.org/schema/p"

 <!--P(属性: properties)命名空间 , 属性依然要设置set方法-->
<bean id="user" class="com.zwt.pojo.User" p:name="zwt" p:age="18"/>

2、c 命名空间注入 : 需要在头文件中加入约束文件(要写 写有参构造 )

导入约束 : xmlns:c="http://www.springframework.org/schema/c"
<!--C(构造: Constructor)命名空间 , 属性依然要设置set方法-->
<bean id="user" class="com.kuang.pojo.User" c:name="狂神" c:age="18"/>

Bean

在Spring中,那些组成应用程序的主体及由Spring IoC容器所管理的对象,被称之为bean。

简单地讲,bean就是由IoC容器初始化、装配及管理的对象 。

几种作用域 :

Singleton

Spring IoC容器中只会存在一个共享的bean实例,并且所有对bean的请求,只要id与该bean定义相匹配,则只会返回bean的同一实例。

Singleton是单例类型,就是在创建起容器时就同时自动创建了一个bean的对象,不管你是否使用,他都存在了,每次获取到的对象都是同一个对象。

注意,Singleton作用域是Spring中的缺省作用域。

 <bean id="ServiceImpl" class="cn.csdn.service.ServiceImpl" scope="singleton">

Prototype

表示一个bean定义对应多个对象实例。

Prototype作用域的bean会导致在每次对该bean请求时都会创建一个新的bean实例。

Prototype是原型类型,它在我们创建容器的时候并没有实例化,而是当我们获取bean的时候才会去创建一个对象,而且我们每次获取到的对象都不是同一个对象。

 <bean id="account" class="com.foo.DefaultAccount" scope="prototype"/>    

 或者 

 <bean id="account" class="com.foo.DefaultAccount" singleton="false"/>

Request

表示在一次HTTP请求中,一个bean定义对应一个实例。

即每个HTTP请求都会有各自的bean实例,它们依据某个bean定义创建而成。

该作用域仅在基于web的Spring ApplicationContext情形下有效。

 <bean id="loginAction" class=cn.csdn.LoginAction" scope="request"/>

针对每次HTTP请求,Spring容器会根据loginAction bean的定义创建一个全新的LoginAction bean实例,

且该loginAction bean实例仅在当前HTTP request内有效,

当处理请求结束,request作用域的bean实例将被销毁。

Session

表示在一个HTTP Session中,一个bean定义对应一个实例。

该作用域仅在基于web的Spring ApplicationContext情形下有效。

 <bean id="userPreferences" class="com.foo.UserPreferences" scope="session"/>

针对某个HTTP Session,Spring容器会根据userPreferences bean定义创建一个全新的userPreferences bean实例,

且该userPreferences bean仅在当前HTTP Session内有效。

当HTTP Session最终被废弃的时候,在该HTTP Session作用域内的bean也会被废弃掉。

自动装配

  • 自动装配是使用spring满足bean依赖的一种方法
  • spring会在应用上下文中为某个bean寻找其依赖的bean。

Spring中bean有三种装配机制,分别是:

  1. 在xml中显式配置;
  2. 在java中显式配置;
  3. 隐式的bean发现机制和自动装配。

自动化的装配bean :

  1. 组件扫描(component scanning):spring会自动发现应用上下文中所创建的bean。
  2. 自动装配(autowiring):spring自动满足bean之间的依赖,也就是我们说的IoC/DI。

组件扫描和自动装配组合发挥巨大威力,使得显示的配置降低到最少。

推荐使用注解进行自动装配

1、在spring配置文件中引入context文件头

xmlns:context="http://www.springframework.org/schema/context"

http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd

2、开启属性注解支持!

<context:annotation-config/>

@Autowired

  • @Autowired是按类型自动转配的,不支持id匹配。
  • 需要导入 spring-aop的包!

测试:

public class User {
@Autowired
private Cat cat; private String str; public Cat getCat() {
return cat;
} public String getStr() {
return str;
}
}

2、此时配置文件内容

<context:annotation-config/>

<bean id="dog" class="com.zwt.pojo.Dog"/>

@Autowired(required=false) 说明:false,对象可以为null;true,对象必须存对象,不能为null。

//如果允许对象为null,设置required = false,默认为true@Autowired(required = false)private Cat cat;

@Qualifier

  • @Autowired是根据类型自动装配的,加上@Qualifier则可以根据byName的方式自动装配
  • @Qualifier不能单独使用。

1、配置文件修改内容,保证类型存在对象。且名字不为类的默认名字!

<bean id="dog1" class="com.zwt.pojo.Dog"/>
<bean id="dog2" class="com.zwt.pojo.Dog"/>
<bean id="cat1" class="com.zwt.pojo.Cat"/>
<bean id="cat2" class="com.zwt.pojo.Cat"/>

2、没有加Qualifier测试,直接报错

3、在属性上添加Qualifier注解

@Autowired
@Qualifier(value = "cat2")
private Cat cat;
@Autowired
@Qualifier(value = "dog2")
private Dog dog;

测试,成功输出!

@Resource

  • @Resource如有指定的name属性,先按该属性进行byName方式查找装配;
  • 其次再进行默认的byName方式进行装配;
  • 如果以上都不成功,则按byType的方式自动装配。
  • 都不成功,则报异常。

实体类:

public class User {
//如果允许对象为null,设置required = false,默认为true
@Resource(name = "cat2")
private Cat cat;
@Resource
private Dog dog;
private String str;
}

beans.xml

<bean id="dog" class="com.kuang.pojo.Dog"/>
<bean id="cat1" class="com.kuang.pojo.Cat"/>
<bean id="cat2" class="com.kuang.pojo.Cat"/>
<bean id="user" class="com.kuang.pojo.User"/>

测试:结果OK

配置文件2:beans.xml , 删掉cat2

<bean id="dog" class="com.kuang.pojo.Dog"/>
<bean id="cat1" class="com.kuang.pojo.Cat"/>

实体类上只保留注解

@Resource
private Cat cat;
@Resource
private Dog dog;

结果:OK

结论:先进行byName查找,失败;再进行byType查找,成功。

小结

@Autowired与@Resource异同:

1、@Autowired与@Resource都可以用来装配bean。都可以写在字段上,或写在setter方法上。

2、@Autowired默认按类型装配(属于spring规范),默认情况下必须要求依赖对象必须存在,如果要允许null 值,可以设置它的required属性为false。

如:@Autowired(required=false) ,如果我们想使用名称装配可以结合@Qualifier注解进行使用

3、@Resource(属于J2EE复返),默认按照名称进行装配,名称可以通过name属性进行指定。

@Autowired先byType,@Resource先byName。

静态and动态代理

AOP的底层机制就是动态代理

静态代理

所谓的代理模式,程序源自于生活

如同现实生活中的你租房子,你看不到房东,但是你依旧通过代理 租到了房东的房子。

优点:

  • 可以使得我们的真实角色更加纯粹 . 不再去关注一些公共的事情 .
  • 公共的业务由代理来完成 . 实现了业务的分工 ,
  • 公共业务发生扩展时变得更加集中和方便 .

缺点 :

  • 类多了 , 多了代理类 , 工作量变大了 . 开发效率降低 .
//抽象角色:租房
public interface Rent {
public void rent();
} //真实角色: 房东,房东要出租房子
public class Host implements Rent{
public void rent() {
System.out.println("房屋出租");
}
} //代理角色:中介
public class Proxy implements Rent { private Host host;
public Proxy() { }
public Proxy(Host host) {
this.host = host;
} //租房
public void rent(){
seeHouse();
host.rent();
fare();
}
//看房
public void seeHouse(){
System.out.println("带房客看房");
}
//收中介费
public void fare(){
System.out.println("收中介费");
}
} //客户类,一般客户都会去找代理!
public class Client {
public static void main(String[] args) {
//房东要租房
Host host = new Host();
//中介帮助房东
Proxy proxy = new Proxy(host); //你去找中介!
proxy.rent();
}
}

动态代理

  • 动态代理分为两类 : 一类是基于接口动态代理 , 一类是基于类的动态代理

    • 基于接口的动态代理----JDK动态代理
    • 基于类的动态代理--cglib
    • 现在用的比较多的是 JAVAssist 来生成动态代理

JDK的动态代理需要了解两个类:

核心 : InvocationHandlerProxy

Object invoke(Object proxy, 方法 method, Object[] args);

proxy - 调用该方法的代理实例

method -所述方法对应于调用代理实例上的接口方法的实例。

方法对象的声明类将是该方法声明的接口,它可以是代理类继承该方法的代理接口的超级接口。

args -包含的方法调用传递代理实例的参数值的对象的阵列,或null如果接口方法没有参数。

原始类型的参数包含在适当的原始包装器类的实例中,例如java.lang.Integer或java.lang.Boolean 。

//生成代理类
public Object getProxy(){
return Proxy.newProxyInstance(this.getClass().getClassLoader(),
rent.getClass().getInterfaces(),this);
}

例子:

//抽象角色:租房
public interface Rent {
public void rent();
} //真实角色: 房东,房东要出租房子
public class Host implements Rent{
public void rent() {
System.out.println("房屋出租");
}
} //ProxyInvocationHandler. java 即代理角色
public class ProxyInvocationHandler implements InvocationHandler {
private Rent rent; public void setRent(Rent rent) {
this.rent = rent;
} //生成代理类,重点是第二个参数,获取要代理的抽象角色!之前都是一个角色,现在可以代理一类角色
public Object getProxy(){
return Proxy.newProxyInstance(this.getClass().getClassLoader(),
rent.getClass().getInterfaces(),this);
} // proxy : 代理类 method : 代理类的调用处理程序的方法对象.
// 处理代理实例上的方法调用并返回结果
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
seeHouse();
//核心:本质利用反射实现!
Object result = method.invoke(rent, args);
fare();
return result;
} //看房
public void seeHouse(){
System.out.println("带房客看房");
}
//收中介费
public void fare(){
System.out.println("收中介费");
} } /租客
public class Client { public static void main(String[] args) {
//真实角色
Host host = new Host();
//代理实例的调用处理程序
ProxyInvocationHandler pih = new ProxyInvocationHandler();
pih.setRent(host); //将真实角色放置进去!
Rent proxy = (Rent)pih.getProxy(); //动态生成对应的代理类!
proxy.rent();
} }

核心:一个动态代理 , 一般代理某一类业务 , 一个动态代理可以代理多个类,代理的是接口!

优点:

  • 可以使得我们的真实角色更加纯粹 . 不再去关注一些公共的事情 .
  • 公共的业务由代理来完成 . 实现了业务的分工 ,
  • 公共业务发生扩展时变得更加集中和方便 .
  • 一个动态代理 , 一般代理某一类业务
  • 一个动态代理可以代理多个类,代理的是接口!

AOP

AOP(Aspect Oriented Programming)意为:面向切面编程 。

通过预编译方式和运行期动态代理实现程序功能的统一维护的一种技术。

AOP是OOP的延续,是软件开发中的一个热点,也是Spring框架中的一个重要内容,是函数式编程的一种衍生范型。

利用AOP可以对业务逻辑的各个部分进行隔离,从而使得业务逻辑各部分之间的耦合度降低,提高程序的可重用性,同时提高了开发的效率。

作用

提供声明式事务,允许用户自定义切面 。

SpringAOP中,通过Advice定义横切逻辑,Spring中支持5种类型的Advice:

  1. 前置增强 (org.springframework.aop.BeforeAdvice) 表示在目标方法执行前来实施增强
  2. 后置增强 (org.springframework.aop.AfterReturningAdvice)

    表示在目标方法执行后来实施增强
  3. 环绕增强 (org.aopalliance.intercept.MethodInterceptor)

    表示在目标方法执行前后同时实施增强
  4. 异常抛出增强 (org.springframework.aop.ThrowsAdvice) 表示在目标方法抛出异常后来实施增强
  5. 引介增强 (org.springframework.aop.introductioninterceptor)

    表示在目标类中添加一些新的方法和属性

即 Aop 在 不改变原有代码的情况下 ,去增加新的功能 。

【重点】使用AOP织入,需要导入一个依赖包!

<!-- https://mvnrepository.com/artifact/org.aspectj/aspectjweaver -->
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.9.4</version>
</dependency>

第一种方式( 通过 Spring API 实现)

//首先编写我们的业务接口和实现类
public interface UserService { public void add(); public void delete(); } public class UserServiceImpl implements UserService{ @Override
public void add() {
System.out.println("增加用户");
} @Override
public void delete() {
System.out.println("删除用户");
} } //然后去写我们的增强类 , 我们编写两个 , 一个前置增强 一个后置增强 public class Log implements MethodBeforeAdvice { //method : 要执行的目标对象的方法
//objects : 被调用的方法的参数
//Object : 目标对象
@Override
public void before(Method method, Object[] objects, Object o) throws Throwable {
System.out.println( o.getClass().getName() + "的" + method.getName() + "方法被执行了");
}
} public class AfterLog implements AfterReturningAdvice {
//returnValue 返回值
//method被调用的方法
//args 被调用的方法的对象的参数
//target 被调用的目标对象
@Override
public void afterReturning(Object returnValue, Method method, Object[] args, Object target) throws Throwable {
System.out.println("执行了" + target.getClass().getName()
+"的"+method.getName()+"方法,"
+"返回值:"+returnValue);
}
} //最后去spring的文件中注册 , 并实现aop切入实现 , 注意导入约束 <?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
http://www.springframework.org/schema/aop/spring-aop.xsd"> <!--注册bean-->
<bean id="userService" class="com.zwt.service.UserServiceImpl"/>
<bean id="log" class="com.zwt.log.Log"/>
<bean id="afterLog" class="com.zwt.log.AfterLog"/> <!--aop的配置-->
<aop:config>
<!--切入点 expression:表达式匹配要执行的方法-->
<aop:pointcut id="pointcut" expression="execution(* com.zwt.service.UserServiceImpl.*(..))"/>
<!--执行环绕; advice-ref执行方法 . pointcut-ref切入点-->
<aop:advisor advice-ref="log" pointcut-ref="pointcut"/>
<aop:advisor advice-ref="afterLog" pointcut-ref="pointcut"/>
</aop:config> </beans>
测试 public class MyTest {
@Test
public void test(){
ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
UserService userService = (UserService) context.getBean("userService");
userService.search();
}
}

Spring的Aop就是将公共的业务 (日志 , 安全等) 和领域业务结合起来 ,

当执行领域业务时 , 将会把公共业务加进来 . 实现公共业务的重复利用

领域业务更纯粹 , 专注领域业务 , 其本质还是动态代理 .

第二种方式 ( 自定义类来实现Aop )

//第一步 : 写我们自己的一个切入类

public class DiyPointcut {

   public void before(){
System.out.println("---------方法执行前---------");
}
public void after(){
System.out.println("---------方法执行后---------");
} } //去spring中配置
<!--第二种方式自定义实现-->
<!--注册bean-->
<bean id="diy" class="com.zwt.config.DiyPointcut"/> <!--aop的配置-->
<aop:config>
<!--第二种方式:使用AOP的标签实现-->
<aop:aspect ref="diy">
<aop:pointcut id="diyPonitcut" expression="execution(* com.zwt.service.UserServiceImpl.*(..))"/>
<aop:before pointcut-ref="diyPonitcut" method="before"/>
<aop:after pointcut-ref="diyPonitcut" method="after"/>
</aop:aspect>
</aop:config> public class MyTest {
@Test
public void test(){
ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
UserService userService = (UserService) context.getBean("userService");
userService.add();
}
}

第三种方式(使用注解实现)

//第一步:编写一个注解实现的增强类

@Aspect
public class AnnotationPointcut {
@Before("execution(* com.kuang.service.UserServiceImpl.*(..))")
public void before(){
System.out.println("---------方法执行前---------");
} @After("execution(* com.kuang.service.UserServiceImpl.*(..))")
public void after(){
System.out.println("---------方法执行后---------");
} @Around("execution(* com.kuang.service.UserServiceImpl.*(..))")
public void around(ProceedingJoinPoint jp) throws Throwable {
System.out.println("环绕前");
System.out.println("签名:"+jp.getSignature());
//执行目标方法proceed
Object proceed = jp.proceed();
System.out.println("环绕后");
System.out.println(proceed);
}
} //第二步:在Spring配置文件中,注册bean,并增加支持注解的配置 <!--第三种方式:注解实现-->
<bean id="annotationPointcut" class="com.zwt.config.AnnotationPointcut"/>
<aop:aspectj-autoproxy/>

通过aop命名空间的<aop:aspectj-autoproxy />声明

自动为spring容器中那些配置@aspectJ切面的bean创建代理,织入切面。

当然,spring 在内部依旧采用AnnotationAwareAspectJAutoProxyCreator进行自动代理的创建工作,

但具体实现的细节已经被<aop:aspectj-autoproxy />隐藏起来了

<aop:aspectj-autoproxy />有一个proxy-target-class属性,默认为false,表示使用jdk动态代理织入增强,

当配为<aop:aspectj-autoproxy poxy-target-class="true"/>时,表示使用CGLib动态代理技术织入增强。

不过即使proxy-target-class设置为false,如果目标类没有声明接口,则spring将自动使用CGLib动态代理。

参考链接:

https://www.bilibili.com/video/BV1WE411d7Dv

Spring-初见的更多相关文章

  1. Spring的事务初见

    一.事务的特性 原子性: 事务是最小的执行单位,不允许分割.事务的原子性确保动作要么全部完成,要么完全不起作用: 一致性: 执行事务前后,数据保持一致: 隔离性: 并发访问数据库时,一个用户的事物不被 ...

  2. 从零一起学Spring Boot之LayIM项目长成记(一) 初见 Spring Boot

    项目背景 之前写过LayIM的.NET版后端实现,后来又写过一版Java的.当时用的是servlet,websocket和jdbc.虽然时间过去很久了,但是仍有些同学在关注.偶然间我听说了Spring ...

  3. 人生若只如初见---Spring概述以及环境的搭建

    Spring 是什么 Spring是由Apache开发的一种轻量型Java框架,能够更加便捷使用JavaBean(之前只有EJB才能实现) Spring的主要优势:分层架构: DAO层:(Data A ...

  4. (spring-第5回【IoC基础篇】)spring容器从加载配置文件到实例化bean的内部工作机制

    前面讲过,spring的生命周期为:实例化前奏-->实例化-->实例化后期-->初始化前期-->初始化-->初始化后期-->bean的具体调用-->销毁前-- ...

  5. Java代理机制之初见(理解及实现)

    都知道Java中的Spring,有一重要思想:AOP,实现原理也就是Java的动态代理机制.初见代理这个名词时,觉得生活中常有代理的这一说法. 那么,在Java中,代理又是什么呢?它又是如何实现的?实 ...

  6. spring batch初识

    Spring Batch是什么?  Spring Batch是一个基于Spring的企业级批处理框架,按照我师父的说法,所有基于Spring的框架都是使用了spring的IoC特性,然后加上自己的一些 ...

  7. Spring--开篇 (spring优缺点、模块组件、各个jar包详解)

    Spring--开篇 分类: SSH&EJB2012-11-23 15:25 4369人阅读 评论(13) 收藏 举报 javaJavaJAVAspringSpringwebWebWEB框架 ...

  8. 基于spring注解AOP的异常处理

    一.前言 项目刚刚开发的时候,并没有做好充足的准备.开发到一定程度的时候才会想到还有一些问题没有解决.就比如今天我要说的一个问题:异常的处理.写程序的时候一般都会通过try...catch...fin ...

  9. 玩转spring boot——快速开始

    开发环境: IED环境:Eclipse JDK版本:1.8 maven版本:3.3.9 一.创建一个spring boot的mcv web应用程序 打开Eclipse,新建Maven项目 选择quic ...

  10. Spring基于AOP的事务管理

                                  Spring基于AOP的事务管理 事务 事务是一系列动作,这一系列动作综合在一起组成一个完整的工作单元,如果有任何一个动作执行失败,那么事务 ...

随机推荐

  1. 注解式项目开发!详细解析Java中各个注解的作用和使用方式

    @Target 作用: 指明了修饰的这个注解的使用范围, 即被描述的注解可以用在哪里 @Target(ElementType.Type) ElementType取值的类型: TYPE: 类,接口或者枚 ...

  2. 一次 RocketMQ 顺序消费延迟的问题定位

    一次 RocketMQ 顺序消费延迟的问题定位 问题背景与现象 昨晚收到了应用报警,发现线上某个业务消费消息延迟了 54s 多(从消息发送到MQ 到被消费的间隔): 2021-06-30T23:12: ...

  3. intelliJ idea 自动修复eslint语法问题

    在要修复代码的文件上或全选需要修复的代码,快捷键:ctrl+shift+a,调出Find Action面板.搜索fix eslint problems,点击此操作,自动修复完成.

  4. centos 8.3安装 一键安装部署gitlab

    安装和配置gitlab必须的依赖包 [root@gitlabdev ~]#dnf install -y curl policycoreutils openssh-server perl 设置开机自启s ...

  5. 大话Java代理模式

    一.什么是代理 首先理解一下什么是代理.简单来说,代理就你要做一件事情,我替你把事情做了.这是现实生活中我们遇到的代理的需求场景.但写代码的时候对代理场景的需求,跟现实场景有点区别,本质上还是帮你做事 ...

  6. SpringMVC(8)国际化

    在SpringMVC(七)格式化显示中我们讲了数据的格式化显示,Spring在做格式化展示的时候已经做了国际化处理,那么如何将我们网站的其它内容(如菜单.标题等)做国际化处理呢?这就是本篇要将的内容- ...

  7. ZYNQ 中PS端GPIO EMIO使用

    ZYNQ 中PS端GPIO EMIO使用 在使用ZYNQ进行开发设计时,往往需要对一些GPIO引脚进行配置,传统的配置方法通常在PL端进行管脚约束之后在Verilog代码中对相应引脚进行配置.这样如果 ...

  8. c语言的自动类型转换(转)

    一.自动转换遵循以下规则: 若参与运算量的类型不同,则先转换成同一类型,然后进行运算. 转换按数据长度增加的方向进行,以保证精度不降低.如int型和long型运算时,先把int量转成long型后再进行 ...

  9. 测试基础(四)Jmeter基础使用

    前言 通过测试基础(三) Jmeter安装 - 大风北吹 - 博客园 (cnblogs.com)安装完成Jmeter后,就可以使用Jmeter进行性能测试. 一.线程组 (1).线程组分类 Jmete ...

  10. iOS基于AVFoundation实现朗读文字

    iOS基于AVFoundation实现朗读文字 1.心理建设 众所周知AVFoundation的朗读是个智障语气,所以想不花钱就只能忍着. 2.speechManager @import AVFoun ...