Spring

作者: 请叫我平爷 | 来源:发表于2022-11-27 21:08 被阅读0次

    v# Spring

    简介

    • 轻量级:spring是非侵入式的,基于Spring开发的应用的对象可以不依赖于Spring的API
    • 依赖注入:(DI---dependency injection、IOC)
    • 面向切面编程(AOP---aspect oriented programming)
    • 容器:spring是一个容器,包含并管理应用对象的生命周期
    • 框架:spring实现了使用简单的组件配置组合成一个复杂的应用,在Spring中可以使用XMl和Java注解组合这些对象
    • 一站式:在IOC和AOP的基础上可以整合各种企业应用的开源框架和开源的第三方类库(Spring自身也提供了展现层SpringMVC和持久层的Spring JDBC)

    IOC、DI

    • IOC: Inversion of control

      • 控制反转,反转资源获取方向,
      • 传统的资源查找方式是要求组件向容器发起请求查找资源,作为回应,容器适时的返回资源
      • IOC是容器主动将资源推送给他所管理的组件,组件所需要做的是选择一种合适的方式来接收资源
      • 也叫被动查找
    • DI:Dependency Injection,

      • IOC的另一种表达方式,组件以一些预先定义好的方式接收来自容器的资源注入,相比IOC而言,这种表述更直接
      • setter方式(属性注入)
        <bean id = "cat" class="com.mi.learn.Cat">
            <property name="name" value="Tom"></property>
        </bean>
        
      • 构造函数
        public class Car{
            private String brand;
            private String corp;
            private int price;
            private int maxSpeed;
        
            public Car(String brand ,String corp ,int price){
                this.brand = brand;
                this.corp = corp;
                this.price = price;
            }
        }
        
        <bean id = "car" class="com.mi.learn.Car">
            <constructor-arg value="Audio"></constructor-arg>
            <constructor-arg value="ShangHai"></constructor-arg>
            <constructor-arg value="300000"></constructor-arg>
        </bean>
        
        <bean id = "car1" class = "com.mi.learn.Car">
            <constructor-arg value="audio" type="java.lang.String"></constructor-arg>
            <constructor-arg type="java.lang.String">
                <value><![CDATA[<ShangHai">]]></value>
            </constructor-arg>
            <constructor-arg type="int">
                <value>250</value>
            </constructor-arg>
        </bean>
        
      • 工厂方法注入
      • 注解依赖:
        • IOC注解:@Component、@Controller、@Server、@Repository
          • 把当前类注入spring容器中
          • value值用于指定bean的id,不写时,就默认是当前类名,首字母改小写。
          • @Component:泛指组件,不好归类
          • @Controller:控制层
          • @Service:业务层
          • @Repository:标注数据访问组件,DAO组件
        • @Autowired
          • 根据对象类型来找,找到就直接通过setter方法注入
          • 存在多个类型的bean,就通过@Qualifier("bean的id")来一起查找
          • 如果IOC容器中没有任何bean的类型和要注入的变量类型匹配,报错
          • IOC容器多个类型匹配时,再按名字查找,如果没有匹配就报错
            • 可能是方法上,可能是变量上
          • 使用注解注入时,set方法就不是必须的了
            //根据id为cat的Cat对象,找不到报错
            @Autowired
            private Cat cat;
            
        • @Qualified
          • 按照类中注入的基础之上再按名称注入
          • 类成员注入时不能单独使用
          • 方法参数注入时可以
          • value用于指定注入bean的id
        • @Resource
          • 根据对象类型查找,找到就直接同setter方法注入
          • 名字找不到就按类型查找。找到多个会报错
          • 直接按照bean的id注入,可以单独使用
          • name用于指定bean的id
            //根据id为cat的Cat对象,找不到报错
            @Resource(name = "cat")
            private Cat cat;
            
        • @Value
          • 用于注入常量数据
            server.port=8001
            
            public class ValueBean {
                //@Value("9999") // 可以直接值注入
                @Value("${server.port}") // 也可以通过SpEL的方式来注入配置文件中的key
                private int port;
            
                @Override
                public String toString() {
                    return "ValueBean{" +
                            "port=" + port +
                            '}';
                }
            }
            
    • XML配置

      • @Autowired
        <context:annotation-config/>
        <bean id="cat" class="com.mi.learn.Cat"/>
        <bean id="dog" class="com.mi.learn.Dog"/>
        
      • @Resource
        <context:annotation-config/>
        
      • @Value
        <context:annotation-config/>
        <!--加载properties文件-->
        <context:property-placeholder local="classpath:db.properties,classpath:server.properties"/>
        <bean id ="valueBean" class="com.mi.learn.ValueBean"/>
        
      • @Component
        <context:annotation-config/>
        <context:component-scan base-package="com.mi.learn"/>
        
    • IOC和DI实际上是同一个东西

      • IOC,字面上,更多强调的是Spring容器帮我们创建对象
      • DI,字面上,Spring不仅帮我们创建对象,还要为该对象设置依赖的数据

    @Scope、@PostConstruct、@PreDestory

    • @Scope
      • 作用域注解
    • @PostConstruct
      • 初始化方法的注解
    • @PreDestory
      • 销毁方法的注解

    @Mapper、@Repository

    • @Mapper,通过mapper.xml中的namespace属性对应的相关mapper类,spring动态的生产bean后注入到serverImpl中
    • @Repository,在spring中配置扫描包的地址,生成DAO层的bean,注入到serviceImpl中

    SpringIOC容器

    Spring提供了两种IOC容器

    • BeanFactory:IOC容器的基本实现
      • 是Spring的基础设施,面向Spring本身
    • ApplicationContext:提供了更多的高级特性,是BeanFactory的子接口
      • 面向使用Spring框架的开发者
        ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
        ApplicationContext ctx1 = new FileSystemXmlApplicationContext("applicationContext.xml");
        
      • ApplicationContext在初始化上下文的时候就实例化所有的单例Bean
      • ConfigurationApplicationContext扩展ApplicationContext,新增refresh()、close(),让ApplicationContext具有启动、关闭、刷新上下文的能力
      • WebApplicationContext是专门为Web应用准备的,允许从相对于web根目录的路径中完成初始化工作
    • 几乎所有的应用场合都是使用ApplicationContext

    AOP Aspect Oriented Programming

    面向切面编程:将涉及多业务流程的通用功能抽取并单独封装,形成独立的切面,在合适的时机将这些切面横向切入到业务流程指定的位置中

    • AOP基本术语:
      • Aspect(切面):对业务主逻辑的一种增强
      • Joint Point(连接点):程序执行的某个特定的位置
        • spring只支持方法的连接点
      • PointCut(切点):切面具体织入的位置。响应的advice将要发生的地方
      • Advice(增强):切面的一种实现,可以完成简单织入功能。通知定义了advice代码切入到目标代码的时间点,advice类型不同,切入时间不同
        • @Before:方法运行前
        • @After:方法运行后
        • @AfterReturning:后置增强,方法正常退出时执行
        • @AfterThrowing:异常抛出增强,方法执行抛出异常后执行
        • @Around:环绕增强,控制切点执行前,执行后,用这个注解,抛出异常会影响@AfterThrowing注解
      • Target(目标对象)
        • 织入advice的目标对象
      • Weaving(织入):把切面应用到目标对象来创建新的代理对象的过程

    pom.xml

    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-aop</artifactId>
    </dependency>
    

    AopMethod

    @Component
    public class AopMethod {
    
        public int add (int a , int b){
            System.out.println("AopMethod add start "+a+" "+b);
            int res = a+b;
            System.out.println("AopMethod end "+res);
    
            return res;
        }
    }
    

    MyAopAspect

    @Aspect
    @Component
    public class MyAopAspect {
    
        @Pointcut("execution(* com.mi.learn.aspect.demo.component.AopMethod.*(..))")
        public void pointCut() {}
    
        @Before("pointCut()")
        public void beforeMethod(JoinPoint joinPoint){
            System.out.println("MyAopAspect.beforeMethod");
        }
    
        @After("pointCut()")
        public void afterMethod(){
            System.out.println("MyAopAspect.afterMethod");
        }
    
    
        @AfterReturning(value = "pointCut()",returning = "result")
        public void afterReturningMethod(JoinPoint joinPoint,Object result){
            System.out.println("MyAopAspect.afterReturningMethod");
        }
    
        @AfterThrowing(value = "pointCut()",throwing = "e")
        public void afterThrowingMethod(JoinPoint joinPoint,Exception e){
            System.out.println("MyAopAspect.afterThrowingMethod");
        }
    
        @Around("pointCut()")
        public Object aroundMethod(ProceedingJoinPoint proceedingJoinPoint){
    
            System.out.println("MyAopAspect.aroundMethod-1 ");
            Object object = null;
            try {
                object = proceedingJoinPoint.proceed();
            } catch (Throwable throwable) {
                throwable.printStackTrace();
            }
            System.out.println("MyAopAspect.aroundMethod-2 object" + object);
            return object;
        }
    }
    

    Test

    @Test
    public void testMethod(){
      int res = method.add(1,4);
      System.out.println("res-->"+res);
    }
    

    log日志

    MyAopAspect.aroundMethod-1 
    MyAopAspect.beforeMethod
    AopMethod add start 1 4
    AopMethod end 5
    MyAopAspect.afterReturningMethod
    MyAopAspect.afterMethod
    MyAopAspect.aroundMethod-2 object 5
    res-->5
    

    事务

    Transactional

    • name 指定选择多个事务管理器中的某个事务管理器
    • propagation 事务传播行为
    • isolation 事务隔离级别
    • timeout 超时
    • read-only 只读

    相关文章

      网友评论

          本文标题:Spring

          本文链接:https://www.haomeiwen.com/subject/vpwylrtx.html