Spring详解

 

Bean的生命周期

 

0,调用BeanFactoryPostProcessor的postProcessBeanFactory方法
1,调用Bean的构造函数(或者工厂方法)实例化Bean.
2,对Bean的成员变量赋值.
3,如果Bean实现了BeanNameAware,调用Bean的setBeanName方法.
4,如果Bean实现了BeanFactoryAware,调用Bean的setBeanFactory方法.
5,如果Bean实现了ApplicationContextAware,调用Bean的setApplicationContext方法.
6,如果容器中配置了BeanPostProcessor,调用BeanPostProcessor的postProcessBeforeInitialization方法(如果有多个,调用每一个)
6,如果Bean实现了InitializingBean,调用Bean的afterPropertiesSet方法.
7,如果Bean配置了init-method方法,调用init-method配置的Bean方法.
8,如果容器中配置了BeanPostProcessor,调用BeanPostProcessor的postProcessAfterInitialization方法.(如果有多个,调用每一个)
9,Bean处于可以使用的状态.
10,Spring容器关闭.
11,如果Bean实现了DisposableBean,调用Bean的destroy方法.
12,如果Bean配置了destroy-method方法,调用destroy-method配置的Bean的方法.

 

 

 

Bean

 

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.BeanFactoryAware;
import org.springframework.beans.factory.BeanNameAware;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.InitializingBean;

/**
 * 测试生命周期的Bean
 */
public class StudentBean implements InitializingBean, DisposableBean, BeanNameAware, BeanFactoryAware {
    private String name;
    private int age;

    private String beanName;//实现了BeanNameAware接口,Spring可以将BeanName注入该属性中
    private BeanFactory beanFactory;//实现了BeanFactory接口,Spring可将BeanFactory注入该属性中

    public StudentBean(){
        System.out.println("【Bean构造方法】学生类的无参构造方法");
    }

    @Override
    public String toString() {
        return "StudentBean{" +
                "name='" + name + '\'' +
                ", age=" + age +
                ", beanName='" + beanName + '\'' +
                '}';
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        System.out.println("【set注入】注入学生的name属性");
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        System.out.println("【set注入】注入学生的age属性");
        this.age = age;
    }

    /**
     * 自己编写的初始化方法
     */
    public void myInit(){
        System.out.println("【init-method】调用init-method属性配置的初始化方法");
    }

    /**
     * 自己编写的销毁方法
     */
    public void myDestroy(){
        System.out.println("【destroy-method】调用destroy-method属性配置的销毁方法");
    }

    /**
     * BeanFactoryAware接口的方法
     * @param beanFactory
     * @throws BeansException
     */
    @Override
    public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
        this.beanFactory = beanFactory;
        System.out.println("【BeanFactoryAware接口】调用BeanFactoryAware的setBeanFactory方法得到beanFactory引用");
    }

    /**
     * BeanNameAware接口的方法
     * @param name
     */
    @Override
    public void setBeanName(String name) {
        this.beanName = name;
        System.out.println("【BeanNameAware接口】调用BeanNameAware的setBeanName方法得到Bean的名称");
    }

    /**
     * InitializingBean接口的方法
     * @throws Exception
     */
    @Override
    public void afterPropertiesSet() throws Exception {
        System.out.println("【InitializingBean接口】调用InitializingBean接口的afterPropertiesSet方法");
    }

    /**
     * DisposableBean接口的方法
     * @throws Exception
     */
    @Override
    public void destroy() throws Exception {
        System.out.println("【DisposableBean接口】调用DisposableBean接口的destroy方法");
    }
}

 

 

 

BeanPostProcessor接口

 

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;

public class MyBeanPostProcessor implements BeanPostProcessor {

    public MyBeanPostProcessor(){
        System.out.println("【BeanPostProcessor接口】调用BeanPostProcessor的构造方法");
    }

    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        System.out.println("【BeanPostProcessor接口】调用postProcessBeforeInitialization方法,这里可对"+beanName+"的属性进行更改。");
        return bean;
    }

    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        System.out.println("【BeanPostProcessor接口】调用postProcessAfterInitialization方法,这里可对"+beanName+"的属性进行更改。");
        return bean;
    }
}

 

 

 

BeanFactoryPostProcessor接口

 

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;

public class MyBeanFactoryPostProcessor implements BeanFactoryPostProcessor {

    public MyBeanFactoryPostProcessor() {
        System.out.println("【BeanFactoryPostProcessor接口】调用BeanFactoryPostProcessor实现类构造方法");
    }

    /**
     * 重写BeanFactoryPostProcessor接口的postProcessBeanFactory方法,可通过该方法对beanFactory进行设置
     */
    @Override
    public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory)
            throws BeansException {
        System.out.println("【BeanFactoryPostProcessor接口】调用BeanFactoryPostProcessor接口的postProcessBeanFactory方法");
        BeanDefinition beanDefinition = beanFactory.getBeanDefinition("studentBean");
        beanDefinition.getPropertyValues().addPropertyValue("age", "21");
    }
}

 

 

 

Spring配置文件beans.xml

 

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"
       xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"
       xsi:schemaLocation="
            http://www.springframework.org/schema/beans
            http://www.springframework.org/schema/beans/spring-beans-3.2.xsd">

    <!--配置Bean的后置处理器-->
    <bean id="beanPostProcessor" class="com.xxx.cyclelife.MyBeanPostProcessor">
    </bean>

    <!--配置BeanFactory的后置处理器-->
    <bean id="beanFactoryPostProcessor" class="com.xxx.cyclelife.MyBeanFactoryPostProcessor">
    </bean>

    <bean id="studentBean" class="com.xxx.cyclelife.StudentBean" init-method="myInit"
          destroy-method="myDestroy" scope="singleton">
        <property name="name" value="xxx"></property>
        <property name="age" value="21"></property>
    </bean>

</beans>

 

 

 

 

 

 

 

常用注解

@Autowire和@Resource

 

 

 

共同点:
均可标注在字段或属性的setter方法上。
都可以通过@Qualifier显式指定 autowired by qualifier name。


区别:
@Autowired是spring的注解,使用AutowiredAnnotationBeanPostProcessor处理依赖注入。
@Resource来自于JSR-250位于java.annotation包,使用CommonAnnotationBeanPostProcessor处理依赖注入。
@Autowired默认 autowired by type,如果失败,则退化为autowired by field name;
@Resource默认autowired by field name,如果失败,则退化为autowired by type。可以使用@Autowired + @Qualifier实现@Resource的效果。
@Autowired有个required属性,配置为false时如果没有找到对应的bean是不会抛异常的。@Resource没有该配置,找不到会抛异常。

 

 

 

@Component和@Service、@Repository、@Controller

 

 

 

使用@Component注解标识类会生成响应的bean,默认的名称(id)是小写开头的非限定类名。也可以指定名称:@Component(“hello”),不推荐使用。

@Controller对应控制层的Bean,@Service对应的是业务逻辑层Bean,@Repository对应数据访问层也就是持久层的Bean。和@Component是等效的,区别在于后三个有具体的业务含义,分别对应web架构的3个分层。推荐使用后三者代替@Component,在spring未来的版本中,@Controller,@Service,@Repository会携带更多语义。并且便于开发和维护。

 

 

 

@Qualifier

 

当容器中存在同样类型的多个bean时,用@Qualifier注解指定注入Bean的名称 。

 

 

@ComponentScan

 

 

 

自动扫描包名下所有声明为Bean的类

 

 

 

@EnableAspectJAutoProxy 

 

 

 

开启Spring对AspectJ的支持

 

 

 

@Bean

 

 

 

注解在方法上,声明当前方法的返回值为一个Bean

 

 

 

@PostConstruct

 

 

 

在构造函数执行完后执行

 

 

 

@PreDestroy

 

 

 

在Bean销毁之前执行

 

 

 

AOP注解(链接git)

@Aspect  //声明为切面
@PointCut //切点,定义拦截规则
@After
@Before
@Around

 

 

@Conditional 

这个注解会检查条件,只有这个条件满足的时候,才会enable某些配置
标注在类上,声明配置类,相当于把该类作为spring的xml配置文件中的来使用。

 

@ConditionalOnClass
当classpath里面有一个或几个指定的类的时候才激活一个配置

@ConditionalOnMissingBean
当一个bean没有创建的时候,创建一个bean

@ConditionalOnBean
@ConditionalOnExpression
@ConditionalOnMissingClass
@ConditionalOnNotWebApplication
@ConditionalOnResource
@ConditionalOnWebApplication


 

@EnableXXX

 

使用@Import注解来做了一个简单的configuration import

@EnableTransactionManagement
启用了声明式的事务管理

@EnableWebMvc
启用Spring MVC

@EnableScheduling
初始化一个定时器。

@EnableConfigurationProperties
自动把一个POJO映射到一个Spring Boot配置文件(默认的是application.properties)里面的属性列表

 

 

 

@Import和@ImportResource

详情请看

 

全局句柄

package com.oppo.push.inbox.util;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Component;

@Lazy(false)
@Component()
public class ApplicationContextHolder implements ApplicationContextAware {
    private final static Logger log = LoggerFactory.getLogger(ApplicationContextHolder.class);
    private ApplicationContextHolder(){}
    private static ApplicationContext applicationContext;

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        ApplicationContextHolder.applicationContext = applicationContext;
        log.info("spring applicationContext init");
    }

    public static ApplicationContext getApplicationContext() {
        if(applicationContext == null)
            throw new IllegalStateException("'applicationContext' property is null,ApplicationContextHolder not yet init.");
        return applicationContext;
    }
}

其他

https://www.cnblogs.com/liaojie970/p/8042686.html

https://www.cnblogs.com/duanxz/p/7493276.html

https://www.cnblogs.com/kungfupanda/p/7747004.html

 

 

未完待续

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值