Spring基础入门笔记(一)

一、Spring概述

1.1 Spring是什么?

spring全家桶:spring , springmvc ,spring boot , spring cloud

spring: 是于 2003 年兴起的一个轻量级的 Java 开发框架,解决企业开发的难度。减轻对项目模块之间的管理,类和类之间的管理, 帮助开发人员创建对象,管理对象之间的关系。

spring核心技术: ioc , aop 。核心目的是为了能实现模块之间,类之间的解耦合。

Spring 的主要作用就是为代码“解耦”,降低代码间的耦合度。就是让对象和对象(模块和模块)之间关系不是使用代码关联,而是通过配置来说明。即在 Spring 中说明对象(模块)的关系。

依赖:classa中使用classb的属性或者方法, 叫做classa依赖classb

Spring 根据代码的功能特点,使用 Ioc 降低业务对象之间耦合度。IoC 使得主业务在相互调用过程中,不用再自己维护关系了,即不用再自己创建要使用的对象了。而是由 Spring容器统一管理,自动“注入”,注入即赋值。 而 AOP 使得系统级服务得到了最大复用,且
不用再由程序员手工将系统级服务“混杂”到主业务逻辑中了,而是由 Spring 容器统一完成“织入”。

1.2 框架怎么学: 框架是一个软件,其它人写好的软件。

1)知道框架能做什么, mybatis–访问数据库, 对表中的数据执行增删改查。
2)框架的语法, 框架要完成一个功能,需要一定的步骤支持的,
3)框架的内部实现, 框架内部怎么做, 原理是什么。
4)通过学习,可以实现一个框架。

二、Ioc 控制反转

2.1 spring的第一个核心功能 ioc

IoC (Inversion of Control) : 控制反转, 是一个理论,概念,思想。描述的是把对象的创建,赋值,管理工作都交给代码之外的容器实现,也就是对象的创建是有其它外部资源完成。

控制: 创建对象,对象的属性赋值,对象之间的关系管理。
反转: 把原来的开发人员管理,创建对象的权限转移给代码之外的容器实现。 由容器代替开发人员管理对象。创建对象,给属性赋值。

正转:由开发人员在代码中,使用new 构造方法创建对象, 开发人员主动管理对象。

       public static void main(String args[]){
            Student student = new Student(); // 在代码中, 创建对象。--正转。

		 }

简单来说,控制反转就是由容器去完成创建对象,对象赋值,对象之间的关系管理的工作。

容器:是一个服务器软件, 一个框架(spring)。

为什么要使用 ioc : 目的就是减少对代码的改动, 也能实现不同的功能,实现解耦合。

2.2 java中创建对象有哪些方式

  1. 构造方法 , new Student()
  2. 反射
  3. 序列化
  4. 克隆
  5. ioc :容器创建对象 (之前的学习过程中Servlet就是IOC的思想体现)
  6. 动态代理

ioc的体现:
servlet
1: 创建类继承HttpServelt
2: 在web.xml 注册servlet ,
使用<servlet-name> myservlet </servlet-name>
<servelt-class>com.bjpwernode.controller.MyServlet1</servlet-class>
3. 没有创建 Servlet对象, 没有 MyServlet myservlet = new MyServlet()
4. Servlet 是Tomcat服务器创建的。 Tomcat也称为容器。
Tomcat作为容器:里面存放的有Servlet对象, Listener , Filter对象

2.3 IoC的技术实现

2.3.1 DI 是ioc的技术实现

DI(Dependency Injection) :依赖注入, 只需要在程序中提供要使用的对象名称就可以, 至于对象如何在容器中创建,赋值,查找都由容器内部实现。

spring是使用di实现了ioc的功能, spring底层创建对象,使用的是反射机制

spring是一个容器,管理对象,给属性赋值, 底层是反射创建对象。

spring-conetxt 和 spring-webmvc是spring中的两个模块

spring-context:是ioc功能的,创建对象的。
spring-webmvc做web开发使用的, 是servlet的升级。
spring-webmvc中也会用到spring-context中创建对象的功能的。

2.3.2 junit : 单元测试

单元测试:一个工具类库,做测试方法使用的。
单元:指定的是方法, 一个类中有很多方法,一个方法称为单元。

使用单元测试
1.需要加入junit依赖。

junit
junit
4.11
test

2.创建测试作用的类:叫做测试类
src/test/java目录中创建类

3.创建测试方法

1)public 方法
 2)没有返回值 void 
 3)方法名称自定义,建议名称是test + 你要测试方法名称
 4)方法没有参数
 5)方法的上面加入 @Test ,这样的方法是可以单独执行的。 不用使用main方法。

2.3.3 为应用指定多个 Spring 配置文件

  1. 多个配置优势
    1.每个文件的大小比一个文件要小很多。效率高
    2.避免多人竞争带来的冲突。

如果你的项目有多个模块(相关的功能在一起) ,一个模块一个配置文件。
学生考勤模块一个配置文件, 张三
学生成绩一个配置文件, 李四

多文件的分配方式:

  1. 按功能模块,一个模块一个配置文件
  2. 按类的功能,数据库相关的配置一个文件配置文件, 做事务的功能一个配置文件, 做service功能的一个配置文件等

2.4 基于XML的DI

2.5 基于注解的DI

基于注解的di: 通过注解完成java对象创建,属性赋值。不再需要在 Spring 配置文件中声明 bean 实例。

2.5.1 使用注解的步骤

(1).加入maven的依赖 spring-context ,在你加入spring-context的同时, 间接加入spring-aop的依赖。
使用注解必须使用spring-aop依赖

(2).在类中加入spring的注解(多个不同功能的注解)

(3).在spring的配置文件中,加入一个组件扫描器的标签,说明注解在你的项目中的位置

```
<!--声明组件扫描器(component-scan),组件就是java对象
    base-package:指定注解在你的项目中的包名。
    component-scan工作方式: spring会扫描遍历base-package指定的包,
       把包中和子包中的所有类,找到类中的注解,按照注解的功能创建对象,或给属性赋值。

   加入了component-scan标签,配置文件的变化:
    1.加入一个新的约束文件spring-context.xsd
    2.给这个新的约束文件起个命名空间的名称
-->
<context:component-scan base-package="com.xzz.ba02" />
```

2.5.2 学习的注解

 (1)@Component
 (2)@Respotory
 (3)@Service
 (4)@Controller
 (5)@Value
 (6)@Autowired
 (7)@Resource

	主要学习@Component
		- 创建对象的, 等同于<bean>的功能
		-  属性:value 就是对象的名称,也就是bean的id值,
		-  value的值是唯一的,创建的对象在整个spring容器中就一个
		-  位置:在类的上面
   @Component(value = "myStudent")等同于
    <bean id="myStudent" class="com.bjpowernode.ba01.Student" />
//使用value属性,指定对象名称
//@Component(value = "myStudent")

//省略value
@Component("myStudent")

//不指定对象名称,由spring提供默认名称: 类名的首字母小写
//@Component

小贴士:
spring中和@Component功能一致,创建对象的注解还有:

  • @Repository(用在持久层类的上面) : 放在dao的实现类上面,
  •           表示创建dao对象,dao对象是能访问数据库的。
    
  • @Service(用在业务层类的上面):放在service的实现类上面,
  •          创建service对象,service对象是做业务处理,可以有事务等功能的。
    
  • @Controller(用在控制器的上面):放在控制器(处理器)类的上面,创建控制器对象的,
  •          控制器对象,能够接受用户提交的参数,显示请求的处理结果。
    

以上三个注解的使用语法和@Component一样的。 都能创建对象,但是这三个注解还有额外的功能。

  • @Repository,@Service,@Controller是给项目的对象分层的。

注意:上面这三种注解虽然和Component功能一致,但是用的地方不同,有自己的特有的场景。那么Component在哪里可以用到呢,就是实现类不是上面三种情景时用Component。

====================================================================================
一个问题:项目中不可能只扫描一个包,扫描多个包的方式有哪些?

指定多个包的三种方式:

  1. 使用多个 context:component-scan 指定不同的包路径
	<context:component-scan base-package="com.xzz.ba01" />
    <context:component-scan base-package="com.xzz.ba02" />
    <context:component-scan base-package="com.xzz.ba03" />
    <context:component-scan base-package="com.xzz.ba04" />
    <context:component-scan base-package="com.xzz.ba05" />
  1. 指定 base-package 的值使用分隔符
    分隔符可以使用逗号(,)分号(;)还可以使用空格,不建议使用空格。
    <context:component-scan base-package="com.xzz.ba01;com.xzz.ba02;com.xzz.ba03;" />

3)base-package 是指定到父包名
base-package 的值是基本包,容器启动会扫描包及其子包中的注解,当然也会扫描到
子包下级的子包。所以 base-package 可以指定一个父包就可以。

<context:component-scan base-package="com.xzz" />

或最顶级包

<context:component-scan base-package="com" />

注意:不建议使用顶级的父包,因为扫描的路径比较多,导致容器启动时间变慢。指定到目标包和合适的就可以了。也就是注解所在包全路径。例如注解的类在 com.xzz.beans 包中.

========================================================================

2.5.3 简单类型属性注入@Value( 掌握)

需要在属性上使用注解@Value,该注解的 value 属性用于指定要注入的值。使用该注解完成属性注入时,类中无需 setter。当然,若属性有 setter,则也可将其加到 setter 上。
在这里插入图片描述

注意
组件扫描器一定不能写错包,如果写错的话,就找不到包进行扫描,也就识别不到注解,也不会创建对象到Spring容器中。

2.5.4 引用类型的赋值

  1. byType 自动注入@Autowired( 掌握)
    需要在引用属性上使用注解@Autowired,该注解默认使用按类型自动装配Bean的方式。使用该注解完成属性注入时,类中无需 setter。当然,若属性有 setter,则也可将其加到 setter 上。
    在这里插入图片描述

  2. byName 自动注入@Autowired 与@Qualifier( 掌握)

需要在引用属性上联合使用注解@Autowired 与@Qualifier。@Qualifier 的 value 属性用于指定要匹配的 Bean 的 id 值。类中无需 set 方法,也可加到 set 方法上。
在这里插入图片描述
@Autowired 还有一个属性 required,默认值为 true,表示当匹配失败后,会终止程序运行。若将其值设置为 false,则匹配失败,将被忽略,未匹配的属性值为 null。建议用true,也就是默认的,可以及时找到错误,进行排错,解决程序中的错误。

2.5.5 JDK 注解@Resource 自动注入( 掌握)

Spring提供了对jdk中@Resource注解的支持。@Resource注解既可以按名称匹配Bean,也可以按类型匹配 Bean。 **默认是按名称注入。**使用该注解,要求 JDK 必须是 6 及以上版本。@Resource 可在属性上,也可在 set 方法上。

在这里插入图片描述
(1 ) byType 注入引用类型
@Resource 注解若不带任何参数,采用默认按名称的方式注入,按名称不能注入 bean,则会按照类型进行 Bean 的匹配注入。(也就是上图所示)

(2 ) byName 注入引用类型
@Resource 注解指定其 name 属性,则 name 的值即为按照名称进行匹配的 Bean 的 id。
在这里插入图片描述

2.5.6 注解与 XML 的 对比

注解优点是:

  • 方便
  • 直观
  • 高效(代码少,速度快,没有配置文件的书写那么复杂)。
    其弊端也显而易见:以硬编码的方式写入到 Java 代码中,修改是需要重新编译代码的。

XML 方式优点是:

  • 配置和代码是分离的
  • 在 xml 中做修改,无需编译代码,只需重启服务器即可将新的配置加载。
    xml 的缺点是:编写麻烦,效率低,大型项目过于复杂。

总结:
需要经常修改的就用XML,无需经常修改的就用注解。

用户处理请求:
用户form ,参数name ,age-----Servlet(接收请求name,age)—Service类(处理name,age操作)—dao类(访问数据库的)—mysql

三、AOP 面向切面编程

Aop:面向切面编程,基于动态代理的,可以使用jdk,cglib两种代理方式。Aop就是动态代理的规范化, 把动态代理的实现步骤,方式都定义好了, 让开发人员用一种统一的方式,使用动态代理。

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

面向切面编程是从动态角度考虑程序运行过程。

3.1 动态代理

动态代理:实现原有代码不变的情况下,通过动态代理可以额外给原有的类增加一些功能。可以在程序的执行过程中,创建代理对象。
通过代理对象执行方法,给目标类的方法增加额外的功能(功能增强)

实现方式:

  • jdk动态代理,使用jdk中的Proxy,Method,InvocaitonHanderl创建代理对象。jdk动态代理要求目标类必须实现接口,通过接口来实现功能增强的。
  • cglib动态代理:第三方的工具库,创建代理对象,原理是继承。 通过继承目标类,创建子类。子类就是代理对象。 要求目标类不能是final的, 方法也不能是final的(因为final方法不能修改)。(没有接口使用该方法)通过子类重写父类的方法实现功能增强。运行效率比JDK高一些,对要求低,不需要实现接口就行,只需要继承就行,大多数类都可以继承。

动态代理的作用:
1)在目标类源代码不改变的情况下,增加功能。
2)减少代码的重复
3)专注业务逻辑代码
4)解耦合,让你的业务功能和日志,事务非业务功能分离。

3.2 Aop:面向切面编程

Aspect: 切面,给你的目标类增加的功能,就是切面。 像上面用的日志,事务都是切面。切面的特点: 一般都是非业务方法,独立使用的。
Orient:面向, 对着。
Programming:编程

oop: 面向对象编程

3.2.1 怎么理解面向切面编程

1)需要在分析项目功能时,找出切面。
2)合理的安排切面的执行时间(在目标方法前, 还是目标方法后)
3)合理的安排切面执行的位置,在哪个类,哪个方法增加增强功能

在这里插入图片描述

术语:
1)Aspect:切面,表示增强的功能, 就是一堆代码,完成某一个功能。非业务功能,常见的切面功能有日志, 事务, 统计信息, 参数检查, 权限验证。
2)JoinPoint:连接点 ,连接业务方法和切面的位置。 实际上就是某类中的业务方法。(比如service中的某些方法)一般指一个方法。
3)Pointcut : 切入点 ,指多个连接点方法的集合。多个方法。程序中可能有多个类都需要切面方面,就用切入点。被标记为 final 的方法是不能作为连接点与切入点的。因为最终的是不能被修改的,不能被增强的。
4)目标对象: 给哪个类的方法增加功能, 这个类就是目标对象。一般来说就是实现业务逻辑的类。
5)Advice:通知,通知表示切面功能执行的时间。通知定义了增强代码切入到目标代码的时间点,是目标方法执行之前执行,还是之后执行等。通知类型不同,切入时间不同。

切入点定义切入的位置,通知定义切入的时间。

一个切面有三个关键的要素:
1)切面的功能代码,切面干什么
2)切面的执行位置,使用Pointcut表示切面执行的位置
3)切面的执行时间,使用Advice表示时间,在目标方法之前,还是目标方法之后。

3.2.2 aop的实现

aop是一个规范,是动态的一个规范化,一个标准

aop的技术实现框架:
1)spring:spring在内部实现了aop规范,能做aop的工作。**spring主要在事务处理时使用aop。**我们项目开发中很少使用spring的aop实现。 因为spring的aop比较笨重。
2)aspectJ: 一个开源的专门做aop的框架。spring框架中集成了aspectj框架,通过spring就能使用aspectj的功能。AspectJ 是 Eclipse 的 的开源项目。

aspectJ框架实现aop有两种方式:

  • 使用xml的配置文件 : 配置全局事务
  • 使用注解,我们在项目中要做aop功能,一般都使用注解, aspectj有5个注解。

在 Spring 中使用 AOP 开发时,一般使用 AspectJ 的实现方式。

3.2.3 学习aspectj框架的使用。

1、切面的执行时间, 这个执行时间在规范中叫做Advice(通知,增强)。在aspectj框架中使用注解表示的,也可以使用xml配置文件中的标签。

1)@Before (前置通知)
在这里插入图片描述
如果我们在切面功能中要使用业务方法的信息,可以使用JoinPoint
在这里插入图片描述

总结
在目标方法执行之前执行。被注解为前置通知的方法,可以包含一个 JoinPoint 类型参数。该类型的对象本身就是切入点表达式。通过该参数,可获取切入点表达式、方法签名、目标对象等。不光前置通知的方法,可以包含一个 JoinPoint 类型参数,所有的通知方法均可包含该参数。

2)@AfterReturning (后置通知)
在目标方法执行之后执行。由于是目标方法之后执行,所以可以获取到目标方法的返回值。该注解的 returning 属性就是用于指定接收方法返回值的变量名的。所以,被注解为后置通知的方法,除了可以包含 JoinPoint 参数外,还可以包含用于接收返回值的变量。该变
量最好为 Object 类型,因为目标方法的返回值可能是任何类型。

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

3)@Around (环绕通知)
在目标方法执行之前之后执行。被注解为环绕增强的方法要有返回值,Object 类型。并且方法可以包含一个 ProceedingJoinPoint 类型的参数。接口 ProceedingJoinPoint 其有一个proceed()方法,用于执行目标方法。若目标方法有返回值,则该方法的返回值就是目标方法的返回值。最后,环绕增强方法将其返回值返回。该增强方法实际是拦截了目标方法的执行。
在这里插入图片描述
在这里插入图片描述

@Around(value = "execution(* *..SomeServiceImpl.doFirst(..))")
    public Object myAround(ProceedingJoinPoint pjp) throws Throwable {

        String name = "";
        //获取第一个参数值
        Object args [] = pjp.getArgs();
        if( args!= null && args.length > 1){
              Object arg=  args[0];
              name =(String)arg;
        }

        //实现环绕通知
        Object result = null;
        System.out.println("环绕通知:在目标方法之前,输出时间:"+ new Date());
        //1.目标方法调用
        if( "zhangsan".equals(name)){
            //符合条件,调用目标方法
            result = pjp.proceed(); //method.invoke(); Object result = doFirst();

        }

        System.out.println("环绕通知:在目标方法之后,提交事务");
        //2.在目标方法的前或者后加入功能

        //修改目标方法的执行结果, 影响方法最后的调用结果
        if( result != null){
              result = "Hello AspectJ AOP";
        }

        //返回目标方法的执行结果
        return result;
    }

4)@AfterThrowing (异常通知)
在目标方法抛出异常后执行。该注解的 throwing 属性用于指定所发生的异常类对象。当然,被注解为异常通知的方法可以包含一个参数 Throwable,参数名称为 throwing 指定的名称,表示发生的异常对象。
在这里插入图片描述
在这里插入图片描述

5)@After (最终通知)
在这里插入图片描述
在这里插入图片描述
注意
无论目标方法是否抛出异常,该方法均会被执行。

在这里插入图片描述

2、表示切面执行的位置,使用的是切入点表达式

		com.service.impl
		com.bjpowrnode.service.impl
		cn.crm.bjpowernode.service


      execution(* *..service.*.*(..))

AspectJ 定义了专门的表达式用于指定切入点。表达式的原型是:

execution(modifiers-pattern? ret-type-pattern
declaring-type-pattern?name-pattern(param-pattern)
throws-pattern?)

解释:

  • modifiers-pattern 访问权限类型 也就是private public protected
  • ret-type-pattern 返回值类型
  • declaring-type-pattern 包名类名
  • name-pattern(param-pattern) 方法名(参数类型和参数个数)
  • throws-pattern 抛出异常类型
    ?表示可选的部分

以上表达式共 4 个部分,execution(访问权限 方法返回值 方法声明(参数) 异常类型)。

切入点表达式要匹配的对象就是目标方法的方法名。所以,execution 表达式中明显就是方法的签名。注意,表达式中未加粗的文字表示可省略部分,各部分间用空格分开。在其中可以使用以下符号:

符号意义
*0至多个任意字符
用在方法参数中,表示任意多个参数
用在包名后,表示当前包及其子包路径
+用在类名后,表示当前类及其子类
用在接口后,表示当前接口及其实现类

========================================================================================
举例:
execution(public * (…))
指定切入点为:任意公共方法。
execution(
set*(…))
指定切入点为:任何一个以“set”开始的方法。
execution(* com.xyz.service..(…))
指定切入点为:定义在 service 包里的任意类的任意方法。
execution(* com.xyz.service….(…))
指定切入点为:定义在 service 包或者子包里的任意类的任意方法。“…”出现在类名中时,后
面必须跟“”,表示包、子包下的所有类。
execution(
…service..(…))
指定所有包下的 serivce 子包下所有类(接口)中所有方法为切入点
execution(
.service..(…))
指定只有一级包下的 serivce 子包下所有类(接口)中所有方法为切入点
execution(
.ISomeService.(…))
指定只有一级包下的 ISomeSerivce 接口中所有方法为切入点
execution(* …ISomeService.(…))
指定所有包下的 ISomeSerivce 接口中所有方法为切入点
execution(* com.xyz.service.IAccountService.(…))
指定切入点为:IAccountService 接口中的任意方法。
execution(
com.xyz.service.IAccountService+.(…))
指定切入点为:IAccountService 若为接口,则为接口中的任意方法及其所有实现类中的任意
方法;若为类,则为该类及其子类中的任意方法。
execution(
joke(String,int)))
指定切入点为:所有的 joke(String,int)方法,且 joke()方法的第一个参数是 String,第二个参
数是 int。如果方法中的参数类型是 java.lang 包下的类,可以直接使用类名,否则必须使用
全限定类名,如 joke( java.util.List, int)。
execution(* joke(String,)))
指定切入点为:所有的 joke()方法,该方法第一个参数为 String,第二个参数可以是任意类
型,如joke(String s1,String s2)和joke(String s1,double d2)都是,但joke(String s1,double d2,String
s3)不是。
execution(
joke(String,…)))
指定切入点为:所有的 joke()方法,该方法第一个参数为 String,后面可以有任意个参数且
参数类型不限,如 joke(String s1)、joke(String s1,String s2)和 joke(String s1,double d2,String s3)
都是。
execution(* joke(Object))
指定切入点为:所有的 joke()方法,方法拥有一个参数,且参数是 Object 类型。joke(Object ob)
是,但,joke(String s)与 joke(User u)均不是。
execution(* joke(Object+)))
指定切入点为:所有的 joke()方法,方法拥有一个参数,且参数是 Object 类型或该类的子类。
不仅 joke(Object ob)是,joke(String s)和 joke(User u)也是。

====================================================================================

3.2.4 项目中aspect的使用步骤

使用aop:目的是给已经存在的一些类和方法,增加额外的功能。 前提是不改变原来的类的代码。

使用aspectj实现aop的基本步骤:
1.新建maven项目
2.加入依赖
1)spring依赖
2)aspectj依赖
3)junit单元测试
3.创建目标类:接口和他的实现类。
要做的是给类中的方法增加功能

4.创建切面类:普通类
1)在类的上面加入 @Aspect
在这里插入图片描述

2)在类中定义方法, 方法就是切面要执行的功能代码
在方法的上面加入aspectj中的通知注解,例如@Before
还需要指定切入点表达式execution()
在这里插入图片描述

5.创建spring的配置文件:声明对象,把对象交给容器统一管理
声明对象你可以使用注解或者xml配置文件

  1. 声明目标对象
    2)声明切面类对象
    3)声明aspectj框架中的自动代理生成器标签。
    自动代理生成器:用来完成代理对象的自动创建功能的。

在这里插入图片描述
执行流程:

  • 在测试类中指定配置文件
  • 根据配置文件创建spring容器,并将配置文件中定义的对象在spring容器中自动创建,赋值,管理
  • 当程序在配置文件读到<aop:aspectj-autoproxy proxy-target-class=“true”/>时,就会扫描容器里面的对象,看这些对象里面是否有aspectj注解,也就是找切面表达式,根据切面表达式将指定类改造为代理对象。
  • 如果<aop:aspectj-autoproxy proxy-target-class=“true”/>在根据切面表达式未能找到指定类的方法时,则不会将对应的类改造为代理对象,也就不会加上代理的功能。

6.创建测试类,从spring容器中获取目标对象(实际就是代理对象)。
通过代理执行方法,实现aop的功能增强。

补充:

  1. Pointcut注解:
    当较多的通知增强方法使用相同的 execution 切入点表达式时,编写、维护均较为麻烦。AspectJ 提供了@Pointcut 注解,用于定义 execution 切入点表达式。其用法是,将@Pointcut 注解在一个方法之上,以后所有的 execution 的 value 属性值均可使用该方法名作为切入点。代表的就是@Pointcut 定义的切入点。这个使用@Pointcut 注解的方法一般使用 private 的标识方法,即没有实际作用的方法。
    在这里插入图片描述
  2. 以上的案例代码中目标代码的类都是有实现一个接口,意味着实现的是JDK的动态代理。如果目标代码(业务逻辑类)没有实现接口的话,使用的是cglib动态代理, spring框架会自动应用cglib。即没有接口则使用的是继承方式
  3. 另外有接口,也可以使用cglib动态代理。(要去applicationContext.xml里面加上以下代码,也就是配置文件里面)该方式在程序执行效率比JDK动态代理高。
    在这里插入图片描述

这些只是在学习过程中整理的笔记,想要学到更多的知识可以阅读官方文档:https://docs.spring.io/spring-framework/docs/current/reference/html/

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
## Spring入门学习 首先认识下Spring的结构 ![架构图](http://www.ibm.com/developerworks/cn/java/j-lo-spring-principle/image001.gif) 然后我们皆可以写我们的demo了 ### 我们的Bean类 对于bean的理解,希望大家是把他看成Object对象,他可以是任何对象,甚至是接口,甚至是抽象方法,当然,具体用法大家在以后的使用中会有所认识的; 写一个简单的bean类 ```java package mybatis.study.start.bean; import lombok.Setter; /** * @program: test * @description: helloworld * @author: cutedog * @create: 2019-02-18 22:48 **/ @Setter public class HelloWorld { private String name; public void pritlnHello(){ System.out.println("Spring 3:Hello"); } } ``` #### 写我们的配置文件 一般都是application.xml文件,放在idea的resource目录下,是一个bean注册的配置文件 内容如下: ```xml <?xml version="1.0" encoding="UTF-8"?> <beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="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-2.5.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd"> <bean id="helloBean" class="mybatis.study.start.bean.HelloWorld"> <property name="name" value="Yiibai" /> </bean> </beans> ``` list<provin> Map<city,provincecitymysqq

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值