Spring

Spring

IOC:控制反转,创建对象的工作由他完成

AOP:面向切面编程,不破坏源代码的情况下增加或者修改功能

IOC

IOC底层为:xml解析,工厂模式和反射

测试时候,先加载spring配置文件,在获取配置创建的对象,最后调用

IOC的重要接口

  • BeanFactory:一般不用,使用时先解析xml文件,运行时才创建对象

  • ApplicationContext:是BeanFactory的加强版,使用时解析xml文件和创建对象

    ApplicationContext有两个重要的实现接口:

    • FileSystemXmlApplicationContext:写入xml在盘中的地址

    • ClassPathXmlApplicationContext:写入xml类路径

spring有两种bean:

1.普通bean:创建什么类型,返回什么类型

2.FactoryBean:创建什么类型,可以返回不同的类型,具体实现方法是implement FactoryBean,然后重写其中的getObject方法,写要返回的类型,在调用时也要更改为自己想要的类型

IOC操作Bean的方式:

基于xml方式

  • 创建对象

    • 创建对象的时候默认使用无参构造,在xml文件中使用Bean标签

    • id属性:起别名,唯一标识

    • name属性:和id属性相似,可以有特殊符号

    • class属性:创建的对象所在的全路径(包类路径)

    • bean的作用域:标签scope。不写默认为singleton为单实例,在加载xml文件的时候就创建对象。prototype多实例,在调用context.getbean时才创建对象

  • 注入属性

    • 正常注入属性两种方式,写get然后new对象调get,有参构造器。

      • 第一种方式get是在xml配置文件中,先写Bean创建对象,内部有property标签,分为name:属性名称和value:属性的值。相当于new对象和调get的工作在xml文件中完成了

        • 如果注入的值为空值,在property标签中不写value,在property标签内写一个null标签

        • 如果注入的值为特殊符号,例如<,必须使用转义字符或者写CDATE

        • 如果注入的是对象,不写value,写ref

        • 还有一种p空间注入,感觉不太清楚明了,底层是set注入

        • 外部bean:前一个bean中赋值propery写name="zly",bean外面再写一个bean,id="zly"

        • 内部bean,bean标签内还能写bean。是在propery标签内再写bean,再写propery赋值

        • 级联赋值:涉及到对象要用ref,前一个bean中赋值propery写name="zly" ref="zly",bean外面再写一个bean,id="zly",内再写propery赋值,相当于外部bean的时候写个ref

        • 注入集合类属性,在bean文件中,property标签中写其他标签,例如<List><Map><Set><array>,在里面在写<value>值

        • 注入集合类属性时注入的为对象,则value不写,写为ref bean:,在外面创建对象,把id写道ref bean中

      • 第二种方式有参构造器是在xml配置文件中,先写Bean创建对象,内部有constructor-arg标签,属性名称和value:属性的值。相当于new对象和有参构造的工作在xml文件中完成了

xml也可自动装配,在bean标签中有个autowire的标签,里面写ByName,或者ByType。省略了在中间使用property方式赋值

在学习了基于注解式的方法后,基于xml式的经典白学,不怎么使用

在xml文件中引入外部配置文件:一般用于链接数据库

使用德鲁伊连接池,先引入jar包,然后写一个jdbc.property文件,写入数据库信息,然后在xml文件中引入context名称空间,然后使用标签引入jdbc.property文件<context:property-placeholder location="classpath:jdbc.properties"/>,最后配置连接池用${}

基于注解式

基于注解式开发的步骤:

1.引入spring中aop依赖

2.在xml配置文件中告诉spring去哪个类扫描注解

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

写入要扫描的类,如果类很多可以用逗号隔开,或者写上层目录

<context:component-scan base-package="com.zly" use-default-filters="false">
    <context:include-filter type="annotation" expression="com.zly.Controller"/>
</context:component-scan>
这段添加了use-default-filters="false",不适用默认规则使用我们自己写的扫描规则,<context:include-filter只扫描后缀是Controller的类
<context:component-scan base-package="com.zly">
    <context:exclude-filter type="annotation" expression="com.zly.Controller"/>
</context:component-scan>
这段有<context:exclude-filter,表示不扫描包含Controller的类

3.写注解

@Component(value=“userservise”)

这个userservise相当于在Bean中的id

括号中的内容可以省略,省略之后默认为类名的开头小写,例如类名为Userservise,则id为userservise

  • 创建对象

    • spring基于bean创建对象的注解

      @Component

      @Service

      @Controller

      @Repository

      这四个注解可以混用,名称不同只是为了方便开发

  • 注入属性

    • 注入属性的时候不需要写set方法,注解帮忙实现了。要先定义类型再注入,例如private UserDao userDao,在这个上面写注解

    • spring基于bean注入属性的注解

      @AutoWired 根据属性注入

      @Qualifier 根据名称注入,一般和@Autowired一起使用,当一个接口中有多个方法时,根据属性注入没法分辨

      @Resource可以根据属性注入,也可以根据名称注入。根据属性直接写,根据名称要写(name="名称"),不是spring中的,官方不建议使用

      @Value注入普通类型属性

全注解式开发(在springboot中会着重讲解,主要使用,现在spring不使用)

  • 实现全注解式开发,就是创建一个类,在类上写注解@Configuration,来代替xml配置文件,再写@ComponentScan(basePackages = {"com.zly"})里面写要扫描的路径。在测试中已经没有xml文件,所以要改为 ApplicationContext applicationContext=new AnnotationConfigApplicationContext(Config.class);

AOP

概念:面向切面编程,在一个功能中增加其他功能,不需要修改源代码,写一个新的模块通过配置文件插入就可以使用。降低了耦合度,提高了代码的复用。

底层原理:动态代理

  • 有接口interface情况:使用JDK动态代理,创造接口实现类的代理对象来实现功能

  • 无接口情况:一般实现是写方法的子类继承,然后重写进行扩展。aop使用CGLIB动态代理,创建子类的代理对象实现功能

基本概念

通知(增强):就是扩展了哪个方法,升级了哪个功能

  • 前置通知,在方法调用前增强的功能@Before

  • 后置通知@AfterReturning

  • 异常通知@AfterThrowing

  • 最终通知@After

  • 环绕通知@Around

    @Component
    @Aspect
    public class UserProxy {
    ​
        @Around("execution(* com.zly.User.add1(..))")
        public void add(ProceedingJoinPoint proceedingJoinPoint)throws Throwable{
            System.out.println("环绕之前...");
            proceedingJoinPoint.proceed();
            System.out.println("环绕之后...");
        }
    }

区别:后置通知是接受到返回值之后通知

最终通知是调用类后就通知

异常通知是出现异常后才通知,出现异常通知不执行后置通知

环绕通知要写不一样的代码

连接点:所有可以增强的方法

切入点:真正增强的方法,是连接点中的几个

切面:动词,表示把通知应用带切入点的过程

aop使用

1.spring中使用aop一般基于AspectJ,AspectJ不是spring中的组成部分,一般和spring框架联合使用

两种使用方式:

  • 基于xml配置文件

  • 基于注解式(常用)

2.导入jar包

3.切入点表达式:告诉要增强哪个切入点

execution(权限修饰符号 返回类型 类全路径 方法名称 参数列表)

权限修饰符一般用*,表示全类型 返回类型可以省略 参数列表用..表示方法中的参数

例1:对com.zly.UserDao中的add方法进行增强

execution(* com.zly.UserDao.add(..))

例2:对com.zly.UserDao中的所有方法进行增强

execution(* com.zly.UserDao.*(..))

例3:对com.zly包中的所有类里面的所有方法进行增强

execution(* com.zly.*.*(..))

抽取切入点:当使用多种通知,切入点表达式相同的时候,可以写一个方法加上@PointCut注解,之后调用时直接写方法名称

@Pointcut("execution(* com.zly.User.add1(..))")
public void num(){
    
}

当多个增强类对一个方法增强,可以写注释@Order(数字)来区分优先级,数字越小,优先级越高

基于注解式开发

1.先在xml配置文件中写明要扫描的类是那些

2.创建子类和增强类的对象,注解式就行

3.在xml文件中开启AspectJ的使用

4.在增强类的类名上写@Aspect,在增强的方法上写是什么类型的@Before......,然后在括号中写切入点表达式

@Component
@Aspect
public class UserProxy {
​
    @Before("execution(* com.zly.User.add1(..))")
    public void add(){
        System.out.println("before.....");
    }
}

<context:component-scan base-package="com.zly"></context:component-scan>
<aop:aspectj-autoproxy></aop:aspectj-autoproxy>

基于配置文件(未学,很少使用)

jdbcTemplete(未学,一般使用mybatis)

事务管理(未学看到springboot再回来)

日志管理

spring中封装了日志,但是不使用,一般使用log4j2。在spring5中不能使用log4j,要使用需要降版本为spring4

使用方法:

1.导入jar包

2.创建log4j.xml配置文件

<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="trace">
  <!-- 配置日志信息输出目的地 -->
  <Appenders>
    <!-- 输出到控制台 -->
    <Console name="Console" target="SYSTEM_OUT">
      <!--配置日志信息的格式 -->
      <PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/>
    </Console>
    <!-- 输出到文件,其中有一个append属性,默认为true,即不清空该文件原来的信息,采用添加的方式,若设为false,则会先清空原来的信息,再添加 -->
    <File name="MyFile" fileName="D:/Log4j2.log" append="false">
      <PatternLayout>
        <!--配置日志信息的格式 -->
        <pattern>%d %p %C{1.} [%t] %m%n</pattern>
      </PatternLayout>
    </File>
  </Appenders>
  <!-- 定义logger,只有定义了logger并引入了appender,appender才会有效 -->
  <Loggers>
    <Root level="info">
      <AppenderRef ref="Console"/>
      <AppenderRef ref="MyFile"/>
    </Root>
  </Loggers>
</Configuration>

spring新功能:(剩下的没看webflux和junit5测试框架)

@Nullable注解:

  1. 使用在方法上面,方法返回值可以为空

  2. 使用在方法的参数上面,参数返回值可以为空

  3. 使用在属性上面,属性的返回值可以为空

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值