• spring基本知识概览


    1.历史及目标

    Rod Johson在2002年《Expert one to one J2EE design and development》,2004年他又推出了一部堪称经典的力作《Expertone-to-one J2EE Development without EJB》,致力于挑战javaEE及EJB的笨重臃肿,将困难的开发任务进行简化,spring不断发展,新增了很多新特性,比如支持REST风格的springMVC,增强安全性的spring security,缓存,消息的支持,spring Boot,spring Cloud等

    2.spring的核心

    依赖注入(dependency injection,DI)和面向切面编程(aspect-oriented programming,AOP)

    3.spring简化开发的四个策略

    1. 基于pojo的轻量级和最小侵入性编程(不强制实现spring接口或继承spring类)
    2. 通过DI和面向接口实现低耦合
    3. 基于切面和惯例进行声明式编程
    4. 通过切面和模板(Template)减少样板式代码

    tips:

    • 对象通过接口表明依赖关系,就能在对象本身不知情的情况下,用不同实现进行替换,只有spring通过它的配置,能了解这些组成部分是如何装配(wiring)起来的
    • 如果由一个对象自己决定做具体实现,那么会导致紧耦合和难以扩展,不如让依赖的对象自己注入进来,由它自己决定要做什么
    • spring通过应用上下文(Application Context)装载bean的定义并组装,不同的上下文实现的区别在于如何加载配置
    • aop允许你把遍布应用各处的功能分离出来形成可重用的组件,如日志、事务、安全
    • Q:我一个接口只有一般只有一种实现,为什么要使用接口?即使也多个实现也不需要进行实现的替换,为什么还要使用spring的DI呢?
      A:之所以使用接口正是“面向接口编程”这一关注点,对象之间只需要知道规范,不必关心实现;使用spring的DI不仅可以进行解耦,并且它利用容器的单例管理帮助你实现了单例,减少了很多创建销毁对象的性能损耗;最后,使用注入,可以更好的使用AOP,用代理类替代真正的实现类。

    4.spring容器(container)

    • spring应用中,对象由spring容器创建和装配,并存在容器中
    • spring有两种类型的容器实现:bean Factory和ApplicationContext,bean工厂往往太低级,应用上下文更受欢迎
      • AnnotationConfigApplicationContext--java配置类加载
      • AnnotationConfigWebApplicationContext--java配置类加载web应用上下文,
      • ClasspathXmlApplicationContext--类路径下的xml加载,
      • FileSystemXmlapplicationcontext--文件系统下的xml加载,
      • XmlWebApplicationContext--web应用下的xml加载

    5.spring模块

    6.spring boot

    以spring的视角,致力于简化spring本身,大量依赖自动配置技术,消除大部分甚至全部spring配置

    7.装配bean的三种方式:

    • xml显式配置(维护已有旧配置时使用,最次)
    • java显式配置(配置不是自己维护的源码,而你需要为这些代码配置bean,次之)
    • 隐式的bean发现机制和自动装配(最优)

    8.自动化装配bean:

    1. 组件扫描(component scanning):spring自动发现上下文中创建的bean
    2. 自动装配(autowiring):spring自动满足bean之间的依赖

    使用方法:

    1. 组件上添加Component注解

      @Component
      public class BraveKnight implements Knight {
    2. 在JavaConfig类(通常会将它放入单独的包中)上启用组件扫描:
      @Configuration
      @ComponentScan
      public class Config {
      
      }
    3. 使用junit4测试
      @RunWith(SpringJUnit4ClassRunner.class)
      @ContextConfiguration(classes = Config.class)
      public class Test {
          
          @Autowired
          private Knight knight;
      
          @org.junit.Test
          public void test1(){
              assertNotNull(knight);
          }
      
      }

    tips:

    • bean的默认ID为类名的第一个字母变小写,使用Autowired注入成员变量时,如果接口只有一个实现,那么变量名称可以随便取都可以找到,当有两个及以上实现时,变量名称需取bean的ID才能找到
    • 设置组件扫描包:
      @ComponentScan(“com.xx”)

    9.通过java代码装配bean

    比起xml装配更强大、类型安全且对重构友好

    @Bean
        public Knight knight(){
            return new BraveKnight() ;
        }

    bean的ID与方法名相同,依赖可以使用构造器注入(强依赖)和setter()方法(可选性依赖)注入

     10.混合配置

    @Import(ss.class)   @ImportResource("xx.xml")

    <bean class="ssConfig" />  <import resource="xx.xml">

    11.多环境装配

    @Profile

    12.条件化的bean

    @Conditional

    13.表示首选bean

    @Primary

    14.bean的作用域

    单例(Singleton):默认,在整个应用只创建bean的一个实例,对象无状态时使用

    原型(Prototype):每次注入或者通过上下文获取的时候,都会创建一个新的bean实例,bean可变,有状态时使用

    @Scope(value=ConfigurableBeanFactory.SCOPE_PROTOTYPE)

    会话(Session):在Web应用中,每个会话创建一个bean

    请求(Request):在Web应用中,每个请求创建一个bean

    @Scope(value = WebApplicationContext.SCOPE_REQUEST,proxyMode=ScopedProxyMode.INTERFACES)

    tips:

    • 在使用Session和Request作用域时,需设置proxyMode属性,考虑将Session或Request属性的bean注入在单例bean时,若系统启动创建单例bean时,此时会话作用域的bean还未存在;另外,系统中会存在多个Session或Request作用域的实例,我们希望单例bean中注入的恰好是当前Session或Request所对应的bean。因此,设置代理后,系统会在被依赖的地方注入一个代理,当代理被调用时,代理会将调用委托给真正的bean
    • bean没有接口时,需使用CGlib生成基于类的代理
      proxyMode=ScopedProxyMode.TARGET_CLASS

    15.AOP术语

    • 通知(Advice):描述切面要完成的工作及什么时候执行
      前置通知(Before),后置通知(After),返回通知(After-returning),异常通知(After-throwing),环绕通知(Around)
    • 连接点(Join point):应用执行中能够插入切面的一个点
    • 切点(Pointcut):匹配通知要织入的一个或多个连接点
    • 切面(Aspect):通知和切点的结合(要做什么,何时,何处)
    • 引入(Introduction):引入允许我们添加新方法或属性
    • 织入(Weaving):织入是把切面应用到目标对象并创建新的代理对象的过程

    16.spring的AOP

    • 织入:代理类封装了目标类,并拦截被通知方法的调用,再把调用转发给真正的目标bean,当代理拦截到方法调用时,在调用目标bean方法之前或之后,会执行切面逻辑
    • 引入:当引入接口的方法被调用时,代理会将调用委托给实现了新接口的某个其他对象。实际上,一个bean的实现被拆分到了多个类中
    • spring在运行时用到被代理的bean时,才会创建代理对象
    • spring只支持方法连接点,AspectJ和JBoss,除了方法切点,还支持字段和构造器接入点

    织入示例:

    1. 定义切面
      @org.aspectj.lang.annotation.Aspect
      @Component
      public class Aspect {
          
          @Pointcut("execution(** springDemo.Knight.embarkOnQuest(..))")
          public void pointCut(){}
          
          @Before("pointCut()")
          public void before(){
              System.out.println("before");
          }
          
          @Around("pointCut()")
          public void around(ProceedingJoinPoint jp){
              System.out.println("before");
              try {
                  jp.proceed();
              } catch (Throwable e) {
                  // TODO Auto-generated catch block
                  e.printStackTrace();
              }
              System.err.println("end");
          }
          
      }
    2. 在javaConfig中启用自动代理功能
      @Configuration
      @ComponentScan
      @EnableAspectJAutoProxy
      public class Config {
      
      }

      xml方式:<aop:aspjectj-autoproxy />

    3. 在切点前后即可看到通知生效

    引入示例:

    1. 创建引入的接口及一个具体实现:
      public interface ImportMethod {
          public void add();
      }
      public class ImportMethodImpl implements ImportMethod {
          @Override
          public void add() {
              System.out.println("add");
          }
      }
    2. 切面定义:
      @org.aspectj.lang.annotation.Aspect
      @Component
      public class Aspect {
          
       @DeclareParents(value="com.alibaba.springDemo.Knight+",defaultImpl=ImportMethodImpl.class)
          public ImportMethod importMethod;
      
      }

      其中value指明了那种类型的bean要引入该接口,“+”表示所有子类型,
      defaultImpl指定了为引入功能提供实现的具体类,
      @DeclareParents注解了要引入的接口

    3. 使用
      ImportMethod im = (ImportMethod)knight;//将bean转为新的接口类型
      im.add();//执行引入方法
  • 相关阅读:
    mysql 统计新增每天数据
    Oracle dg下掉一个从库
    rman全备脚本
    Linux Shell 统计一(行列)数值的总和及行、列转换
    pt工具加字段脚本
    MySQL慢日志切割邮件发送脚本
    MySQL主从复制邮件报警脚本
    读书清单
    数据库学习笔记
    JAVAEE学习笔记
  • 原文地址:https://www.cnblogs.com/qilong853/p/6641274.html
Copyright © 2020-2023  润新知