javascript
java成员属性生命周期,Spring注解 - 生命周期、属性赋值、自动装配
一、Bean的生命周期
流程
Bean創建 —— 初始化 —— 銷毀
創建:
單實例:在容器啟動時創建對象
多實例:每次調用時創建對象
初始化:
都是在對象創建完成后,調用初始化方法
銷毀:
單實例:容器關閉時,調用銷毀方法
多實例:容器不會管理這個bean,只能手動調用銷毀方法
實現方式
在 @Bean 注解上指定初始化(initMethod)、銷毀方法(destroyMethod) @Bean(initMethod = "init", destroyMethod = "destroy")
public Car car(){
return new Car();
}
讓Bean實現 InitializingBean 和 DisposableBean 接口,重寫它們的方法 public class Cat implements InitializingBean, DisposableBean {
public Cat() {
System.out.println("Cat...Construct...");
}
@Override
public void afterPropertiesSet() throws Exception {
System.out.println("Cat...init...");
}
@Override
public void destroy() throws Exception {
System.out.println("Cat...destroy...");
}
}
使用 JSR250 中的 @PostConstruct 和 @PreDestroy 注解標注初始化、銷毀方法 public class Dog {
public Dog() {
System.out.println("Dog...Construct...");
}
@PostConstruct
public void init(){
System.out.println("Dog...init...");
}
@PreDestroy
public void destroy(){
System.out.println("Dog...destroy...");
}
}
實現BeanPostProcessor接口,重寫
postProcessBeforeInitialization(在初始化之前工作)
postProcessAfterInitialization(在初始化之后工作) public class MyBeanPostProcessor implements BeanPostProcessor {
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
System.out.println("postProcessBeforeInitialization" + beanName);
return bean;
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
System.out.println("postProcessAfterInitialization" + beanName);
return bean;
}
}
二、屬性賦值相關注解
作用:
? 添加在字段上,用于給屬性賦值
屬性:
value:指定要傳入的值
用法:
public class Person {
@Value("張三") //普通方式賦值
private String name;
@Value("#{20 - 1}") //使用SpEL表達式
private Integer age;
@Value("${person.nickName}") //使用 ${} 讀取配置文件內容
private String nickName;
//省略getter setter toString方法
}
上述第三種方式顯然是不能讀取到的,我們需要配置一下配置文件的位置,使用到下面這個注解
@PropertySource
作用:
? 讀取指定的外部配置文件,將K/V鍵值對保存到運行的環境變量中,用 ${} 來獲取
屬性:
name:給屬性源指定一個名稱
value:要加載的配置文件的路徑,可以指定多個
ignoreResourceNotFound:是否忽略資源未找到的情況,默認false
encoding:給定資源的特定字符編碼,例如 “UTF-8”
factory:指定一個自定義屬性源工廠,默認使用 PropertySourceFactory
用法:
在 resources 目錄下創建一個 properties 文件,內容如下
person.nickName=小張
然后在配置類上標注 @PropertySource("classpath:person.properties") 即可
可以直接在@Value注解中獲取,也可以通過 ioc 容器對象獲取
ApplicationContext context = new AnnotationConfigApplicationContext(SpringConfiguration4.class);
String nickName = context.getEnvironment().getProperty("person.nickName");
System.out.println(nickName);
三、自動裝配相關注解
Spring 利用依賴注入(DI),完成對IOC容器中各個組件的依賴關系賦值
@Autowired
默認按照類型去容器中尋找對應的組件,如果只有一個就賦值
如果找到多個相同類型的組件,再按照屬性名尋找
有一個required屬性,默認是true;
可以寫在構造器、方法、參數、屬性上
@Qualifier
一般配合 @Autowired 使用,指定需要裝配的組件的id,@Autowired 就直接按照id注入。
如果 id 對應的組件不存在,并且沒有指定 required = false,則會報錯
@Primary
讓Spring進行自動裝配的時候,首先選擇標注了@Primary的組件
如果已經使用 @Qualifier 指明了要裝配的組件,則不生效
👇 不常用的兩個自動注入注解:
@Resource(JSR250)
java規范里的注解,和@Autowired一樣可以實現自動裝配
默認使用變量名作為 id,不能配合@Qualifier @Primary使用
@Inject(JSR330)
和@Autowired一樣,但是沒有required屬性,需要導入 javax.inject 的 jar 包
javax.inject
javax.inject
1
@Profile
指定組件在哪個環境下才被注冊到容器中,不指定則在哪個環境都注冊
可以指定多個環境,default為默認環境
可以寫在配置類上
還可以用代碼的方式指定環境
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(SpringConfiguration5.class);
applicationContext.getEnvironment().setActiveProfiles("prod");
四、使用 Spring 容器底層組件
對于自定義組件,如果想要使用Spring容器底層組件,可以實現Aware接口的子接口(xxxAware),如下圖所示
@Component
public class TestAware implements ApplicationContextAware {
private ApplicationContext applicationContext;
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
System.out.println("傳入的IOC容器:" + applicationContext);
this.applicationContext = applicationContext;
}
}
這些 xxxAware 的功能都是通過 ApplicationContextAwareProcessor 來處理的
class ApplicationContextAwareProcessor implements BeanPostProcessor {
private final ConfigurableApplicationContext applicationContext;
private final StringValueResolver embeddedValueResolver;
/**
* Create a new ApplicationContextAwareProcessor for the given context.
*/
public ApplicationContextAwareProcessor(ConfigurableApplicationContext applicationContext) {
this.applicationContext = applicationContext;
this.embeddedValueResolver = new EmbeddedValueResolver(applicationContext.getBeanFactory());
}
@Override
@Nullable
public Object postProcessBeforeInitialization(final Object bean, String beanName) throws BeansException {
AccessControlContext acc = null;
if (System.getSecurityManager() != null &&
(bean instanceof EnvironmentAware || bean instanceof EmbeddedValueResolverAware ||
bean instanceof ResourceLoaderAware || bean instanceof ApplicationEventPublisherAware ||
bean instanceof MessageSourceAware || bean instanceof ApplicationContextAware)) {
acc = this.applicationContext.getBeanFactory().getAccessControlContext();
}
if (acc != null) {
AccessController.doPrivileged((PrivilegedAction) () -> {
invokeAwareInterfaces(bean);
return null;
}, acc);
}
else {
invokeAwareInterfaces(bean);
}
return bean;
}
//根據傳入bean的類型來為bean注入不同的組件
private void invokeAwareInterfaces(Object bean) {
if (bean instanceof Aware) {
if (bean instanceof EnvironmentAware) {
((EnvironmentAware) bean).setEnvironment(this.applicationContext.getEnvironment());
}
if (bean instanceof EmbeddedValueResolverAware) {
((EmbeddedValueResolverAware) bean).setEmbeddedValueResolver(this.embeddedValueResolver);
}
if (bean instanceof ResourceLoaderAware) {
((ResourceLoaderAware) bean).setResourceLoader(this.applicationContext);
}
if (bean instanceof ApplicationEventPublisherAware) {
((ApplicationEventPublisherAware) bean).setApplicationEventPublisher(this.applicationContext);
}
if (bean instanceof MessageSourceAware) {
((MessageSourceAware) bean).setMessageSource(this.applicationContext);
}
if (bean instanceof ApplicationContextAware) {
((ApplicationContextAware) bean).setApplicationContext(this.applicationContext);
}
}
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) {
return bean;
}
}
```
總結
以上是生活随笔為你收集整理的java成员属性生命周期,Spring注解 - 生命周期、属性赋值、自动装配的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: php测试框架,PHPUnit使用
- 下一篇: SpringBoot使用StringRe