spring作用、spring注解、管理对象的作用域与生命周期

1. 作用

创建和管理对象,使得开发过程中,可以不必使用new关键字创建对象,而是直接获取对象!并且,还可以通过一些配置,使得某些获取到的对象,其中某些属性已经是被赋值的!

2. Spring注解

在Spring中,定义了一系列的注解,可以取代几乎所有的XML配置!
尽管使用注解可以完成此前的许多配置,但是,基于Spring的项目仍需要Spring的配置文件!

2.1 常用注解

使用注解的方式来创建和管理对象,首先,必须在Spring的配置文件中添加组件扫描:

<!-- 组件扫描 -->
<!-- 仅在组件扫描的包下的类,才会被Spring管理 -->
<!-- 某个类,如果在扫描范围中,且添加了注解,则会被Spring管理 -->
<!-- base-package:扫描的根包 -->
<!-- 根包:父级包,Spring扫描时,会扫描其各层级子包 -->
<!-- 当配置为cn.tedu.spring时 -->
<!-- cn.tedu.spring.dao或cn.tedu.spring.entity这些子包都会被扫描 -->
<context:component-scan base-package="cn.tedu.spring.entity" />

然后,确保需要被管理的类都在以上配置的包中(也可以在其子包中),并且,在类的声明之前添加注解:

@Component
在默认情况下,被管理的类的bean id是与类的名称相同,且首字母小写的!例如类名是User,则默认的bean id是user,或类名是UserDao,则默认的bean id是userDao。

如果需要自定义bean id,可以在注解中添加bean id:

@Component("bean-id")
与@Component作用相同的注解还有:

@Controller
@Service
@Repository
其中,@Component是通用注解,即对任意类都可以添加该注解,@Controller是对控件器类的注解,@Service是对业务类的注解,@Repository是对持久层类的注解。

不过,以上这4种的作用和使用方式完全相同!只是语义不同,即从语法上表达的意义不相同,应该根据类的定位来选取 其中的某个注解!

2.2 【了解】管理对象的作用域与生命周期

由Spring所管理的对象,默认都是饿汉式单例的,通过@Scope注解可以配置某个类被Spring管理时,是否是单例的:

@Scope("prototype")
public class ...
常用的配置方式有@Scope("singleton")和@Scope("prototype")。

如果需要配置该类最终是否是懒加载的,可以使用@Lazy注解,当添加了该注解后,就是懒加载模式,即:只有第1次获取对象时,才会创建对象,而在加载Spring配置文件的过程中,并不会把对象创建出来!

关于@Lazy也可以配置值,例如@Lazy(true)或@Lazy(false)。

饿汉式:一开始就已准备好了,随时都有的吃!

懒汉式:不到逼不得已,不干活!

注意:是否懒加载,是建立在单例的基础之上的!如果不是单例的,则懒加载的配置是无效的!

作用域:在多大的范围内是有效的!对于变量/对象而言,作用域就是它存在的时长,即何时创建及何时销毁!由于单例的对象都是static实现的,也就涉及创建时间和销毁时间的问题!而非单例的,作用域与普通的局部变量相同!

简单的懒汉式单例代码(没有解决线程安全问题):

public class King {
    private static King king = null;

    private King() {
    }

    public static King getInstance() {
        if (king == null) {
            king = new King();
        }
        return king;
    }

}

由Spring管理的对象,也存在生命周期问题,毕竟单例模式的类的对象何时创建、何时销毁,是我们无法确定的!为了确保初始化和销毁工作的正常执行,Spring允许在类中自定义初始化方法和销毁方法,使用了@PostConstruct注解的方法是生命周期初始化方法,会在构造方法之后被自动调用,使用了@PreDestroy注解的方法是生命周期销毁方法,会在Spring容器销毁并释放资源的前一刻被自动调用。

注意:以上2个方法是在javax包中定义的,使用之前,需要为项目添加Tomcat运行环境,否则无法识别!

注意:以上生命周期方法是建立在单例模式之下的,对于非单例模式而言,以上生命周期方法其实没有意义!

2.3 自动装配

当使用了自动装配后,由Spring管理的对象时,会自动尝试为各属性注入值,值的来源可以是其它bean,例如:

public class UserService {
    public IUserDao userDao;
}

public class UserDao1 implements IUserDao {
}

如果以上2个类都是由Spring管理的,则在创建UserService对象时,会尝试自动的将UserDao对象作为其属性值!

自动装配的常用模式有byName和byType,前者表示根据名称来装配,即:要求bean id与属性名保持一致,后者表示根据类型来装配,即bean的类型与属性的类型保持一致(允许是接口与实现类的关系,也允许是父子级继承的关系),不过,根据类型装配,要求匹配该类型的对象必须是有且仅有1个,如果有2个,则会抛出异常,无法装配!

我来吐槽

*

*