关于Spring框架

目录

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

关于Bean Name 被Spring管理的对象都可以称之为:Spring Bean。

关于@Autowired的装配过程

字段注入:

Setter注入:

构造方法注入:

关于Spring自动调用构造方法 使用组件扫描来创建Spring Bean时,Spring框架会自动调用组件类的构造方法,规则如下:

关于Spring Bean的生命周期

关于自定义的方法:

关于IoC与DI

IoC(Inversion of Control): 控制反转,即将各对象的控制权交给了Spring框架


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

由于Spring会保管(管理)所创建的对象,当需要时,可以通过Spring获取这些对象,所以,Spring框架也被称之为“Spring容器”。

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

通过Spring创建对象 -- 1. 组件扫描

在配置类上通过@ComponentScan注解,可以配置“组件扫描”,则加载此配置类时,Spring框架就会开启组件扫描,过程中,会扫描对应的包及其子孙包,如果这些包中存在“组件类”,则Spring会自动创建这些组件类的对象。

在Spring Boot项目中,启动类上添加了@SpringBootApplication注解,此注解的元注解中就包含@SpringBootConfiguration和@ComponentScan,并且,@SpringBootConfiguration的元注解中包含@Configuration,即:

 @SpringBootApplication

-- @SpringBootConfiguration

-- -- @Configuration

-- @ComponentScan

所以,在默认情况下,Spring Boot启用时就会执行组件扫描!

 在@ComponentScan注解上可以配置扫描的根包(basePackage),如果没有配置此属性,则默认为当前配置类所在的包!

在Spring Boot项目中,可以配置@SpringBootApplication的scanBasePackages属性来指定组件扫描的根包。

仅当添加了组件注解的类才被视为“组件类”,典型的组件注解是@Component,另外,还有其它组件注解:

@Controller:添加在控制器类上的注解

@Service:添加在业务类上的注解

@Repository:添加在数据访问类上的注解 在Spring框架的作用范围内,以上3个注解与@Component注解的作用、用法是完全等效的,只是语义不同!

 在Spring框架中,另外还有@Configuration注解也是组件注解的一种,但是,Spring框架会使用“CGLib代理模式”来处理!

在Spring MVC框架中,又加入了一些新的组件注解,包括:

@RestController

@ControllerAdvice

@RestControllerAdvice

 通过Spring创建对象 -- 2. @Bean方法 在配置类中,可以自定义方法,方法的返回值类型就是你希望Spring创建对象的类型,并且,在方法体中,自行编写可以创建出此类型对象的代码,最终,在方法上添加@Bean注解,例如:

@Configuration

public class BeanConfiguration {

@Bean
public ICategoryService categoryService() {
    return new CategoryServiceImpl();
}

@Bean
public CategoryController categoryController(ICategoryService categoryService) {
    // 假设CategoryController中存在带参数的构造方法
    return new CategoryController(categoryService); 
}

@Bean
public AlbumController albumController() {
    return new AlbumController();
}

}

当加载此配置类时,Spring框架会自动调用这些@Bean方法,则Spring框架会得到这些方法返回的对象!

关于通过Spring创建对象的做法的选取 如果需要创建对象的类是自定义的,可以优先考虑使用组件扫描的做法!

如果需要创建对象的类不是自定义的,则只能使用@Bean方法的做法!

关于Bean Name 被Spring管理的对象都可以称之为:Spring Bean。

每个Spring Bean都有Name,即名称。

如果是通过组件扫描创建的Spring Bean,默认的名称取决于类型的名称,如果类名的第1个字母是大写的,且第2个字母是小写的,则名称是将类名的首字母改为小写,例如CategoryServiceImpl的Bean名称就是categoryServiceImpl,如果不符合首字母大写且第2个字母小写,则Bean名称就是类名。另外,还可以在配置组件注解的属性来指定某个名称,例如:

@Service("categoryService")
public class CategoryServiceImpl implements ICategoryService {
}

如果是通过@Bean方法创建的Spring Bean,默认名称就是@Bean方法的名称,或者,可以配置@Bean注解的参数来指定某个名称,例如:

@Configuration

public class BeanConfiguration {

@Bean("categoryService")
public ICategoryService categoryService() {
    return new CategoryServiceImpl();
}

}

关于自动装配 自动装配:当组件类的属性需要值时,或被Spring调用的方法的参数需要值时,Spring框架会自动从容器找到合适的对象,用于为此属性 / 此参数赋值!

合适的对象:名称匹配的,类型匹配的

例如,在属性上添加@Autowired注解,即可表示“需要自动装配”的意义,则Spring框架会尝试为此属性执行自动装配:

@RestController

public class CategoryController {

@Autowired
private ICategoryService categoryService;

}或

@Service

public class CategoryServiceImpl implements ICategoryService {

@Autowired
private CategoryMapper categoryMapper;

}

 在处理自动装配时,可用的注解有@Resource和@Autowired,它们的区分主要在于:

 @Resource是javax.annotation包中的注解, @Autowired是Spring注解

如果你不使用Spring框架,而是使用其它框架实现自动装配,@Resource注解均可使用,而仅当使用Spring时才可以使用  

@Autowired  

由于Spring框架普及程度非常高,所以使用@Autowired是完全没有问题的  

@Resource是优先根据名称来匹配的,如果无匹配,则按照类型来匹配,而@Autowired是优先按照类型查找匹配的对象,如果存在多个类别匹配的,则按照名称来匹配 关于名称的匹配,需要Spring Bean名称与被装配的属性 / 参数的名称保持完全一致。  

 当使用@Resource时,可以配置此注解的name属性,用于指定Spring Bean的名称,例如:

@Resource(name = "categoryServiceImpl")
private ICategoryService categoryService;

 当使用@Autowired时,只能匹配使用@Qualifier注解来指定Spring Bean的名称,例如:

 @Autowired @Qualifier("categoryServiceImpl") private ICategoryService categoryService;

 如果某个方法的参数需要注入值,与参数匹配的Spring Bean超过1个,且各Spring Bean与参数名称都不匹配,使用@Resource是无解的,只能通过在各参数上添加@Qualifier来配置Spring Bean的名称!

关于@Autowired的装配过程

首先,会查找匹配类型的Spring Bean的数量,然后:  

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

true:无法装配,在启动时报错,例如:  

 Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'cn.tedu.csmall.product.service.ICategoryService' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}

 false:放弃装配,在启用时不会报错,后续使用过程中可能会出现NPE

 1个:直接装配,且成功

 多个:尝试按照名称进行匹配,如果可以匹配,则成功装配,否则,启动时报错,例如:

 Caused by: org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type 'cn.tedu.csmall.product.service.ICategoryService' available: expected single matching bean but found 2: categoryServiceImpl,categoryServiceImpl2

关于为属性注入值的做法 当组件类的属性需要值时,有3种可行的做法:

字段注入:

在属性上添加@Autowired,例如:

 @Service

public class CategoryServiceImpl implements ICategoryService {

@Autowired
private CategoryMapper categoryMapper;

}

Setter注入:

在方法上添加@Autowired,并在方法体中为属性赋值,例如:

@Service

public class CategoryServiceImpl implements ICategoryService {

private CategoryMapper categoryMapper;

@Autowired
public void setCategoryMapper(CategoryMapper categoryMapper) {
    this.categoryMapper = categoryMapper;
}

}

构造方法注入:

在被Spring调用的构造方法上添加参数,并通过此参数为属性赋值,例如:

@Service

public class CategoryServiceImpl implements ICategoryService {

private CategoryMapper categoryMapper;

public CategoryServiceImpl(CategoryMapper categoryMapper) {
    this.categoryMapper = categoryMapper;
}

}

注意:理论上并不推荐字段注入,所以,在IntelliJ IDEA中也有相关提示:

理论上推荐的是构造方法注入,但是,构造方法注入对可能出现的增减属性并不友好,并且,当需要注入值的属性较多时,构造方法的参数列表也会很长,这是不合适的!

注意:在属性上使用@Resource注解也可以实现自动装配,并且,IntelliJ IDEA并不会提示灰色的波浪线,但是,并不表示“推荐使用@Resource取代@Autowired”,只是IntelliJ IDEA并不检查@Resource注解,并且,@Resource注解不支持其它注入方式。

关于Spring自动调用构造方法 使用组件扫描来创建Spring Bean时,Spring框架会自动调用组件类的构造方法,规则如下:

如果类没有显式的添加构造方法,则会自动调用默认的构造方式 如果类中仅有1个构造方法,无论是否有参数,Spring都会尝试自动调用

如果类中有多个构造方法,在默认情况下,Spring将自动调用无参数的构造方法(如果存在的话),如果你希望Spring调用特定的构造方法,则需要在此构造方法上添加@Autowired 关于Spring Bean的作用域 所有Spring Bean默认都是单例的,如果希望某个Spring Bean不是单例的,可以通过@Scope注解进行配置。

如果是通过组件扫描创建的Spring Bean,则在组件类上添加

@Scope("prototype")

如果是通过@Bean方法创建的Spring Bean,则在@Bean方法上添加@Scope("prototype")

注意:Spring Bean的表现特征可能是单例的,但Spring并不是通过单例模式来实现的

所有单例的Spring Bean默认都是预加载(相当于单例的饿汉式)的,如果希望某个Spring Bean是懒加载的,可以通过@Lazy注解进行配置。

如果是通过组件扫描创建的Spring Bean,则在组件类上添加@Lazy 如果是通过@Bean方法创建的Spring Bean,则在@Bean方法上添加    @Lazy

关于Spring Bean的生命周期

在Spring Bean归属的类中,可以自定义“初始化”和“销毁”的生命方法,则Spring框架会在创建对象之后自动调用“初始化”的生命周期方法,并在销毁对象之前调用“销毁”的生命周期方法。

关于自定义的方法:

应该是公有的 应该是void返回值类型 销毁方法可以使用布尔类型的返回值 方法名称是自定义的 参数列表应该为空 仅当添加了@PostConstruct注解的方法,才是“初始化”的生命周期方法,此方法会在构造方法之后自动执行。

仅当添加了@PreDestroy注解的方法,才是“销毁”的生命周期方法,此方法会在销毁当前类的对象之前自动执行。

例如:

@PostConstruct
public void init() {
    log.debug("执行生命周期方法:CategoryController的初始化方法");
}

@PreDestroy
public void destroy() {
    log.debug("执行生命周期方法:CategoryController的销毁方法");
}

关于IoC与DI

IoC(Inversion of Control): 控制反转,即将各对象的控制权交给了Spring框架

DI(Dependency Injection):依赖注入,即为各依赖项注入值

Spring框架负责的创建对象、管理对象都是Spring IoC的表现。

Spring框架通过DI完成了IoC,即DI是实现手段,IoC是需要实现的目标。

关于Spring AOP 再议~~~~~~

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值