Spring框架进阶(一)常见组件

20 篇文章 1 订阅
11 篇文章 0 订阅

目录

1、Spring基本编程思想

2、配置组件

2.1、@Configuration IOC容器

2.2、@ComponentScan 指定读取目录

 2.3、@Scope 作用域

2.4、@Lazy 懒加载

2.5、@Conditional 条件加载

2.6、@Import 外部引入

 2.7、生命周期控制

2.7.1、注解控制

2.7.2、接口实现

2.7.3、@Bean的参数实现

2.7.4、生命周期统一管理

2.8、Bean注册方式总结

3、自动装配组件

3.1、@Component 组件声明

3.2、@Value 普通数据赋值

3.3、@Autowired 类型装配

3.4、@PropertySource 配置文件赋值

3.5、@Qualifier 多实例指定

3.6、@Primary 首选者

3.7、@Resource 名称装配

4、织入组件

4.1、ApplicationContextAware

4.2、BeanDefinitionRegistryPostProcessor

5、切面组件

5.1、@EnableTransactionManagement

5.2、@Transactional


Spring是Java开发中最重要的开发框架,可以说现在所有的Java开发者都必须要了解和使用的一种框架。 

1、Spring基本编程思想

Spring的编程思想
Spring思想应用场景特点
OOP

Object Oriented Programming(面向对象编程)

用程序归纳总结一切事务

封装,继承,多态
BOP

Bean Oriented Programming(面向Bean编程)

面向Bea你(普通的Java类)设计程序,解放程序员

Bean是一切的开始
AOP

Aspect Oriented Programming(面向切面编程)

找出多个类中具有规律的代码,开发时拆开,运行时合并,面向切面编程,即面向规则编程

解耦
IOC

Inversion of Control(控制反转)

将new对象的动作交给Spring管理,并由Spring保存已创建的对象(IOC容器)

转交控制权给容器
DI/DL

Dependency Injection(依赖注入)或Dependency Lookup(依赖查找)

依赖注入,依赖查找,Spring不禁保存自己创建的对象,而且保存对象与对象之间的关系,注入即赋值,主要是三种方式:

1、构造方法

2、set注入

3、直接赋值

自动赋值

2、配置组件

2.1、@Configuration IOC容器

@Configuration注解起到的功能是将一个类作为IOC容器,在类的内部方法上,如果增加了@Bean注解,则将这个方法返回的类作为Bean装载到IOC中

具体使用方式如下:

@Configuration
public class config {
    
    @Bean
    public User user(){
        return new User();
    }
}

在程序启动之后,IOC就会加载一个User的Bean,可以通过类型或者名称两种方式进行获取。依照名称的方式进行获取的话,在@Bean没有指定名称时,按照规则:

  1. 创建的Bean名称默认为类名小写,即user
  2. 其次会将函数名称指定为Bean
  3. 如果指定@Bean("user"),则依照指定名称进行获取。
@Configuration
public class config {

    @Bean("user")
    public User user(){
        return new User();
    }
}

2.2、@ComponentScan 指定读取目录

在配置类上添加@ComponentScan注解,该注解默认会扫描该类所在的包下所有的配置类。

 具体使用方式如下:

@ComponentScan("com.spring.example.courseone.project")
public class Config {
}

 增加这个注解之后,将按照默认规则对包下的类进行加载。

默认规则为,只扫描带有@Controller,@Service,@Component,@Repository注解的类。

除了按照默认规则之外,还有其他的规则。

增加注解@Filter,这个注解属于@ComponentScan,可以根据FilterType的类型对规则进行定义。

FilterType是一个枚举类,其中包含几种可以使用的过滤方式,比如注解,类,切点,正则表达式,自定义规则。

public enum FilterType {
    ANNOTATION,
    ASSIGNABLE_TYPE,
    ASPECTJ,
    REGEX,
    CUSTOM;

    private FilterType() {
    }
}

 使用注解过滤器,指定包下类所加载的注解类型,即可指定加载Bean

@Configuration
@ComponentScan(value = "com.spring.example.courseone.project",
        includeFilters = {
                @ComponentScan.Filter(type = FilterType.ANNOTATION, value = {Controller.class})})
public class ComponentScanConfig {
}

 使用类过滤器,指定包下类,即可指定加载类进入IOC

@Configuration
@ComponentScan(value = "com.spring.example.courseone.project",
        includeFilters = {
                @ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE, value = {Person.class})})
public class ComponentScanConfig {
}

 使用自定义过滤器,指定一个自定义的过滤器类,即可让将指定的类型装载。

@Configuration
@ComponentScan(value = "com.spring.example.courseone.project",
        includeFilters = {
                @ComponentScan.Filter(type = FilterType.CUSTOM, value = {MyTypeFilter.class})})
public class ComponentScanConfig {
}

 自定义过滤器,需要继承TypeFilter接口,实现match方法,完成自定义规则的构建。

match的两个参数,metadataReader具有正在操作的类的信息,metadataReaderFactory具有上下文中所有的信息,可以根据这些能获取到的数据,进行对应的过滤

public class MyTypeFilter implements TypeFilter {

    /**
     * 自定义过滤规则
     * 
     * @param metadataReader        当前正在操作的类的信息
     * @param metadataReaderFactory 上下文中所有的信息
     * @return 是否加载
     * @throws IOException IO错误
     */
    @Override
    public boolean match(MetadataReader metadataReader, MetadataReaderFactory metadataReaderFactory) throws IOException {
        //获取当前类的所有注解信息
        AnnotationMetadata annotationMetadata = metadataReader.getAnnotationMetadata();
        //获取当前类的所有信息
        ClassMetadata classMetadata = metadataReader.getClassMetadata();
        //获取当前类的所有资源信息
        Resource resource = metadataReader.getResource();

        String className = classMetadata.getClassName();
        if (className.contains("User")) {
            return true;
        }
        return false;
    }
}

 2.3、@Scope 作用域

用于指定类的作用域

 具体使用方式如下:

@Configuration
public class ScopeConfig {
    
    @Bean
    @Scope("prototype")
    public Person person() {
        return new Person();
    }
}
  1.  prototype:原型,多实例
  2. singleton:单例
  3. request:web模块,同一次请求只创建一个对象
  4. session:web模块,同一个session只创建一个对象
  5. 默认:同singleton,单例

2.4、@Lazy 懒加载

表示延迟初始化

 具体使用方式如下:

@Configuration
public class LazyConfig {

    @Bean
    @Lazy
    public Person person() {
        System.out.println("创建person");
        return new Person();
    }
}

在容器IOC初始化的时候,这个类不会被加载,只有在使用的时候才会被加载,但是要注意,只有单例Bean才可以使用这个注解

2.5、@Conditional 条件加载

Spring4开始提供,它的作用是按照条件判断Bean是否装载到IOC中

创建ConditionOne,实现Condition接口,完成matches类,这里可以用beanFactory实现对Bean的加载监控,确定条件

public class ConditionOne implements Condition {

    @Override
    public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
        ConfigurableListableBeanFactory beanFactory = context.getBeanFactory();
        Environment environment = context.getEnvironment();
        if (beanFactory.containsBean("user")) {
            return true;
        }
        return false;
    }
}

创建ConditionTwo,实现Condition接口,完成matches类,这里可以用Environment 实现对环境的配置监控,确定条件

public class ConditionTwo implements Condition {

    @Override
    public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
        ConfigurableListableBeanFactory beanFactory = context.getBeanFactory();
        Environment environment = context.getEnvironment();
        String property = environment.getProperty("os.name");
        if (property.contains("Window")) {
            return true;
        }
        return false;
    }
}

将条件放入@Conditional注解中,即可实现对应条件的加载

@Configuration
public class ConditionalConfig {

    @Bean
    public User user() {
        System.out.println("创建user");
        return new User();
    }

    @Conditional(ConditionOne.class)
    @Bean
    public Person sam() {
        System.out.println("创建sam");
        return new Person();
    }

    @Conditional(ConditionTwo.class)
    @Bean
    public Person lily() {
        System.out.println("创建lily");
        return new Person();
    }
}

除了基础注解@Conditional,还有一些实现注解,同样常用,就不再一一列举

2.6、@Import 外部引入

导入外部资源

@Import注解使用起来非常简单,可以直接对外部类进行注入

@Configuration
@Import(User.class)
public class ImportsConfig {
}

除了直接使用,还可以一次加载多个,这就需要继承ImportSelector接口来实现

public class MyImportSelector implements ImportSelector {

    @Override
    public String[] selectImports(AnnotationMetadata importingClassMetadata) {
        return new String[] {
                "com.spring.example.courseone.project.model.Cat","com.spring.example.courseone.project.model.Dog"
        };
    }
}

 在@Import注解里加上MyImportSelector类

@Configuration
@Import({User.class,MyImportSelector.class})
public class ImportsConfig {
}

可以发现,使用@Import注解加载的类都是全类名加载

 想要实现按照某些条件进行加载,用@Import同样可以达成,需要实现ImportBeanDefinitionRegistrar接口。

可以看到,需重写的方法带有参数BeanDefinitionRegistry ,它可以获取到当前IOC的Bean,也可以将Bean注册到IOC中。

public class MyImportBeanDefinitionRegistrar implements ImportBeanDefinitionRegistrar {

    @Override
    public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
        boolean cat = registry.containsBeanDefinition("com.spring.example.courseone.project.model.Cat");
        boolean dog = registry.containsBeanDefinition("com.spring.example.courseone.project.model.Dog");
        if (cat && dog) {
            registry.registerBeanDefinition("user", new RootBeanDefinition(User.class));
        }
    }
}

在@Import注解中加入 MyImportBeanDefinitionRegistrar 类

@Configuration
@Import({User.class, MyImportSelector.class, MyImportBeanDefinitionRegistrar.class})
public class ImportsConfig {
}

 2.7、生命周期控制

2.7.1、注解控制

类的生命周期可以使用注解进行控制

  1. @PostConstruct,指定初始化方法,作用域为方法
  2. @PreDestroy,指定销毁方法,作用域为方法
  3. @DependsOn,定义Bean初始化及销毁时的顺序
@Component
public class CourseA {

    public CourseA() {
        System.out.println("创建课程");
    }

    @PreDestroy
    public void close() {
        System.out.println("销毁课程");
    }

    @PostConstruct
    public void start() {
        System.out.println("初始化课程");
    }
}

2.7.2、接口实现

除了使用注解,还可以实现 InitializingBean, DisposableBean接口

@Component
public class CourseB implements InitializingBean, DisposableBean {
    @Override
    public void destroy() throws Exception {
        System.out.println("销毁课程");
    }

    @Override
    public void afterPropertiesSet() throws Exception {
        System.out.println("初始化课程");
    }
}

2.7.3、@Bean的参数实现

还可以使用@Bean注解

public class CourseC {

    public CourseC() {
        System.out.println("Course构造");
    }

    public void start() {
        System.out.println("开始上课");
    }

    public void close() {
        System.out.println("停止上课");
    }
}
@Configuration
@ComponentScan("com.spring.example.courseone.project.model")
public class LifeCycleConfig {

    @Bean(initMethod = "start", destroyMethod = "close")
    public CourseC Course() {
        return new CourseC();
    }
}

2.7.4、生命周期统一管理

除了这些方式吗,还可以实现BeanPostProcessor接口

 实现BeanPostProcessor接口之后,可以统一管理所有Bean的创建和销毁过程,不需要再单独实现。

@Component
public class MyBeanPostProcessor implements BeanPostProcessor {

    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        System.out.println("创建之前 " + beanName);
        return bean;
    }

    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        System.out.println("创建之后 " + beanName);
        return bean;
    }
}

2.8、Bean注册方式总结

  1. @Bean直接导入单个类
  2. @ComponentScan扫描指定包下的类
  3. @Import直接注入
  4. 实现ImportSelector
  5. 实现ImportBeanDefinitionRegistrar
  6. FactoryBean负责注册Bean,BeanFactory负责从容器中获取Bean

3、自动装配组件

3.1、@Component 组件声明

@Component是声明组件的注解,@Controller,@Service,@Repository三个注解是子类,用于标记不用的业务层级,本身并无其他作用和意义

3.2、@Value 普通数据赋值

@Value注解需要在IOC托管的Bean中才能生效

  1. 可以对参数直接赋值
  2. 允许逻辑计算
  3. 读取配置文件的配置数值
public class Teacher {

    @Value("山姆")
    private String name;
    @Value("#{20-2}")
    private int age;
    @Value("${teacher.sex}")
    private String sex;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public String getSex() {
        return sex;
    }

    public void setSex(String sex) {
        this.sex = sex;
    }
}

3.3、@Autowired 类型装配

@Autowired注解的作用是按类型装配,无法按名称装配。如果想要用名称装配,需要配合@Qualifier注解使用。对于@Service等注解,加入容器的Bean的默认名称为类名首字母小写,这也就意味着,@Qualifier注解的优先级高于@Autowired

@Controller
public class MyController {
    
    @Autowired
    private MyService myService;
}
@Controller
public class MyController {

    @Qualifier("myService")
    @Autowired
    private MyService myService;
}

3.4、@PropertySource 配置文件赋值

@PropertySource读取指定配置文件的数值

@Configuration
@PropertySource("classpath:application.properties")
public class PropertySourceConfig {

    @Bean
    public Teacher teacher() {
        return new Teacher();
    }
}

3.5、@Qualifier 多实例指定

在有多个同类的Bean的情况下,可以使用@Qualifier注解指定Bean的名字来确定最终使用哪一个Bean,可以和@Autowired注解配合使用。

@Controller
public class MyController {

    @Qualifier("service")
    @Autowired
    private MyService myService;
}

3.6、@Primary 首选者

在具有多个同类型,同名的Bean时,需要@Primary确定IOC最优先使用的Bean,避免程序运行出现问题

@Configuration
public class PrimaryConfig {

    @Primary
    @Bean("teacher")
    public Teacher teacherA() {
        return new Teacher();
    }

    @Bean("teacher")
    public Teacher teacherB() {
        return new Teacher();
    }
}

3.7、@Resource 名称装配

@Resource的作用与@Autowired相同,但是查找顺序不同,默认按名称装配,当找不到与名称匹配的Bean时才按照类型装配,如果指定名称,则只按照名称寻找。

@Controller
public class MyController {

    @Resource(name = "myService")
    private MyService myService;
}

4、织入组件

4.1、ApplicationContextAware

可以通过上下文环境对象得到Spring容器中的Bean

4.2、BeanDefinitionRegistryPostProcessor

BeanDefinitionRegistryPostProcessor实现了BeanFactoryPostProcessor接口,是Spring框架的BeanDefinitionRegistry的后处理器,用来注册额外的BeanDefinition

5、切面组件

5.1、@EnableTransactionManagement

添加对事物的管理

@SpringBootApplication
@EnableTransactionManagement
public class CourseOneApplication {

    public static void main(String[] args) {
        ApplicationContext applicationContext = SpringApplication.run(CourseOneApplication.class, args);
        for (String className : applicationContext.getBeanDefinitionNames()) {
            System.out.println(className);
        }
    }

}

5.2、@Transactional

配置声明式事物信息,只需要在方法上添加此注解即可开启事务

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
手把手视频详细讲解项目开发全过程,需要的小伙伴自行百度网盘下载,链接见附件,永久有效。 优势亮点(简化) 本次课程以SpringData为中心,重点讲解了其JPA组件,扩展讲解了redis,mongDB,ES组件,并且对部分组件做了必要的源码分析。而且在课程的最后部分加入了一个综合案例,可以将前面章节所学知识点应用到一个项目中,帮助学生理解消化。 配图(持久层技术,无界面) 课程主要内容 第一章 SpringData概述 1.持久层开发的问题 2.SpringData简介 第二章 JPA回顾 1.JPA基础 2.JPA实战 3.JPA的重要API介绍 第三章 SpringData JPA基础 1.SpringData JPA简介 2.SpringData JPA快速入门 3.SpringData Jpa运行原理分析 第四章 SpringData JPA的多种查询方式 1.父接口方法查询 2.方法命名规则查询 3.JPQL查询 4.本地SQL查询 5.Specifications动态查询 第五章 SpringData JPA实现多表操作 1.多表关系分析 2.案例表间关系 3.一对一关系 4.一对多关系 5.多对多关系 第六章 SpringData Redis 1.SpringData Redis简介 2.Redis环境搭建 3.SpringData Redis入门案例 4.SpringData Redis的序列化器 5.SpringData Redis运行原理分析 6.SpringData Redis常见操作 第七章 Repository和Template的选用 第八章 SpringData ElasticSearch 1.SpringData ElasticSearch简介 2.ElasticSearch环境搭建 3.ElasticSearch基础知识回顾 4.SpringData ElasticSearch入门案例 5.SpringData ElasticSearch实现CRUD操作 第九章 SpringData MongDB 1.SpringData MongDB简介 2.MongDB环境搭建 3.MongDB基础知识回顾 4.SpringData MongDB入门案例 5.SpringData MongDB实现CRUD操作 第十章 综合案例 1.案例说明及思路分析 2.代码实现

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值