一、Spring框架

1. Spring框架

1.1. Spring框架的作用

(1)Spring框架主要解决了创建对象和管理对象的相关问题。

(2)通过Spring创建并管理对象,可以使得开发者不再反复关心对象的创建过程,并且,默认情况下,由Spring创建的对象都是单例的,这是非常有必要的!

(3)由Spring创建的对象通常称之为Spring Bean。

由于Spring会创建并管理很多对象,所以Spring也通常被称之为Spring容器。

1.2. Spring框架的依赖项

Spring框架的基础依赖项是:spring-context。

1.3. 使用Spring框架创建对象

1.3.1. 组件扫描

(1)在配置类上,添加@ComponentScan注解可以开启组件扫描。

    在Spring Boot项目中,启用类上的@SpringBootApplication注解中包含@ComponentScan。

    关于@SpringBootApplication注解:

    @SpringBootApplication

        -- @ComponentScan

        -- @SpringBootConfiguration

            -- -- @Configuration

        另外,如果没有在@ComponentScan上配置扫描的包,默认扫描的是当前配置类所在的包。

    (2)在类上添加@Component或基于@Component的组合注解,即可将类标记为组件类。

        在Spring框架中,组件注解有:

            @Component:添加在类上,标记当前类是组件类,可以通过参数配置Spring Bean名称。

            @Controller:添加在类上,标记当前类是控制器组件类,用法同@Component。

            @Service:添加在类上,标记当前类是业务逻辑组件类,用法同@Component。

            @Repository:添加在类上,标记当前类是数据访问组件类,用法同@Component。

            @Configuration:添加在类上,仅添加此注解的类才被视为配置类,通常不配置注解参数。

        在Spring MVC框架中,还新增了组件注解:

            @RestController:添加在类上,标记此类是一个“响应正文”的控制器类。

            @ControllerAdvice:添加在类上,标记此类中特定的方法将作用于每次处理请求的过程中。

            @RestControllerAdvice:添加在类上,是@ControllerAdvice和@ResponseBody的组合注解。

           Spring框架在执行组件扫描时,会扫描所配置的包及其子孙包,并尝试创建所有组件类的对象。

        这种做法只适用于自定义的类。

1.3.2. @Bean方法

(1)在配置类中,可以自行设计方法,返回所需的对象,并在方法上添加`@Bean`注解,则Spring会自动调用此方法,并管理此方法返回的对象。

    @Configuration

    public class BeanConfiguration {

        @Bean

        public UserController userController() {

            return new UserController();

        }

    }

这种做法适用于所有类型创建对象,但一般用于创建非自定义类的对象。

1.4. Spring Bean的作用域

(1)默认情况下,被Spring管理的对象都是单例的,也可以通过@Scope("prototype")修改为非单例的(相当于局部变量)。

(2)被Spring管理的单例的Spring Bean,默认情况下,都是预加载的(相当于饿汉式的单例模式),也可以通过@Lazy注解修改为懒加载的(相当于懒汉式的单例模式)。

注意:不要把Spring和单例模式这种设计模式直接划等号,只是Spring管理的对象的特征与单例模式的相同而已。

如果使用组件扫描的方式创建对象,则在类上添加`@Scope`或`@Lazy`来配置作用域,如果使用`@Bean`方法的方式创建对象,则在方法上添加这些注解来配置作用域。

1.5. Spring Bean的生命周期

仅当Spring Bean是单例的,才有必要讨论生命周期问题。

(1)在自定义的组件类中,可以自定义方法,并在方法添加@PostConstruct和@PreDestroy注解,将方法标记为初始化方法和销毁方法。

(2)在使用@Bean方法的情况下,可以在@Bean注解上配置initMethod和destroyMethod属性,来指定初始化方法和销毁方法的名称。

(3)初始化方法会在创建对象、完成自动装配之后,被Spring框架自动调用。

(4)销毁方法会在Spring框架销毁对象的前一刻被自动调用。

1.6. 自动装配

(1)自动装配:当某个属性,或某个被Spring自动调用的方法的参数需要值时,Spring会自动从容器中找到合适的值,为属性或参数注入值。

    示例:为属性注入值

    @RestController

    public class UserController {

        @Autowired

        private UserMapper userMapper;

    }

    示例:为方法的参数注入值

    @RestController

    public class UserController {

        private UserMapper userMapper;


        //                    ↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓ 自动装配

        public UserController(UserMapper userMapper) {

            this.userMapper = userMapper;

        }

    }

(2)如果类中仅有1个构造方法,不需要添加`@Autowired`注解;如果类中有多个构造方法,Spring会尝试调用无参数的构造方法,如果某个构造方法添加了`@Autowired`注解,则必然调用添加了注解的构造方法。

    @RestController

    public class UserController {

        private UserMapper userMapper;

        @Autowired

        //                        ↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓ 自动装配

        public void setUserMapper(UserMapper userMapper) {

            this.userMapper = userMapper;

        }

    }

    @Configuration

    public class BeanConfiguration {

        @Bean

    //                                  ↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓ 自动装配

        public UserController userController(UserMapper userMapper) {

            UserController userController = new UserController();

            userController.setUserMapper(userMapper);

            return userController;

        }

    }

    除此以外,通过@Value注解也适用以上做法!

(3)使用@Resource注解也可以实现自动装配,但是,它不可以添加在构造方法上!并且,它是javax包下的注解!从装配机制上,@Resource是先根据名称装配,再根据类型装配,而@Autowired是先根据类型进行查找,当冲突时再尝试根据名称装配。

(4)关于@Autowired的装配机制,它是先根据类型查找匹配类型的Spring Bean的数量,然后:

    0个:取决于`@Autowired`注解的`required`属性的值

      true(默认):装配失败,加载Spring时抛出`NoSuchBeanDefinitionException`异常。

      false:放弃装配,但是,后续可能出现NPE(空指针异常)。

    1个:直接装配,且成功

      多个:将尝试根据名称进行装配:

      存在名称匹配的:装配成功

      不存在名称匹配的:装配失败,加载Spring时抛NoUniqueBeanDefinitionException异常。

    另外,关于名称匹配:

        Spring Bean的名称与属性(或参数)的名称相同

        属性(或参数)的名称与Spring Bean的名称相同

        通过`@Resource`的`name`属性指定Spring Bean的名称;通过`@Qulifier`注解指定Spring Bean的名称,结合`@Autowired`的机制一起使用

1.7. 概念

(1)IOC(Inversion of Control):控制反转,指的是将对象的创建、管理等控制权交给了框架

(2)DI(Dependency Injection):依赖注入,为对象的依赖项(类中的属性)注入值

Spring框架通过DI完善了IoC。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

友情链接更多精彩内容