【7.27】spingIOC

spring

1.spring框架原理介绍、spring框架环境搭建

1.Spring框架是轻量级的JavaEE框架
2.Spring可以解决企业应用开发的复杂性
3.Spring有两个核心部分:IOC和Aop

  • IOC:控制反转,把创建对象的过程交给Spring进行管理
  • Aop:面向切面编程,不修改源代码进行功能增强

4.Spring特点

  • 非侵入的
  • 方便解耦,简化开发
  • Aop变成支持
  • 方便程序测试
  • 方便和其他框架进行整合
  • 方便进行事物操作
  • 降低API开发难度

spring环境的搭建

  • 使用创建一个maven的web项目
  • 在pom.xml中导入spring项目所需的包。
    spring项目所需的四个jar包是spring-core,spring-beans,spring-context,spring-expression。
    但是由于最终是要整合SSM开发web项目,这里就使用spring-web和spring-webmvc这两个包就行了。
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-web</artifactId>
            <version>5.3.13</version>
        </dependency>

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-webmvc</artifactId>
            <version>5.3.13</version>
        </dependency>
        
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.13.1</version>
            <scope>test</scope>
        </dependency>
  • 在resources目录下添加spring配置文件springcontext.xml。该配置文件的作用主要是定义bean、开启注解扫描、aop的配置等等。
  • 在web.xml中初始化spring容器。
    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>classpath:springcontext.xml</param-value>
    </context-param>
    <!--设置监听器-->
    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>
  • 配置tomcat服务器spring项目就搭建完成了。

2.学习创建Bean的方式及实现原理、Bean种类、Bean生命周期

Bean的创建

1、创建一个BeanFactory。
2、完成对xml配置文件和注解的扫描,将bean封装为BeanDefinition。
3、将BeanDefinition加入到BeanFactory。
4、添加并启动BeanFactory后置处理器。
5、增强BeanDefinition功能,补充bean。例如ConfigurationClassPostProcessor就是一个BeanFactory后置处理器,可以将@Configuration注解下的bean添加到BeanFactory,也可以解析@ComponentScan注解,扫描对应的包。
6、BeanDefinition通过反射创建bean对象。
7、启动bean后置处理器。BeanPostProcess可以增强bean的功能,如在实例化前后增强bean功能,Spring中内置的AutowiredAnnotationBeanPostProcessor可以处理@Autowire和@Value注解,提供依赖注入的支持。
8、实例化bean对象
9、依赖注入。
8、初始化。

下面是对bean的创建过程的演示

public class BeanLifeCycle {
    public static void main(String[] args) {
        //1、创建一个BeanFactory。
        GenericApplicationContext beanFactory = new GenericApplicationContext();
        //2、完成对xml配置文件和注解的扫描,将bean封装为BeanDefinition。
        //会得到一个bean为com.fiber.config.StudentConfig@564fabc8,但是不能得到里面定义bean
        beanFactory.registerBean("studentConfig",StudentConfig.class);
        //3、添加并启动BeanFactory后置处理器。这时可以处理@ComponentScan和@Bean了
        //得到扫描的com.fiber.bean.AddressConfig$$EnhancerBySpringCGLIB$$1abb854f@791f145a
        //以及定义的student1,address1,address2这个bean。
        beanFactory.registerBean("configurationScan", ConfigurationClassPostProcessor.class);
        //4、注册bean后处理器,处理@Autowired,@Value注解
        beanFactory.getDefaultListableBeanFactory().setAutowireCandidateResolver(
                new ContextAnnotationAutowireCandidateResolver()
        );
        beanFactory.registerBean(AutowiredAnnotationBeanPostProcessor.class);
        //注册bean后处理器,处理@Resources,PostProcess,PreDestroy注解
        beanFactory.registerBean(CommonAnnotationBeanPostProcessor.class);
        
        beanFactory.refresh();
        beanFactory.getBeansOfType(Object.class).values().forEach(System.out::println);
        beanFactory.close();
    }
}

Bean的种类
  • 普通bean:bean的class类型和创建的bean对象类型一样。
    <bean id="address3" class="com.fiber.pojo.Address"/>
  • FactoryBean:class类型和bean对象类型不一样。创建一个工厂类,实现FactoryBean接口
public class AddressFactory implements FactoryBean<Address> {

    @Override
    public Address getObject() throws Exception {
        Address address = new Address();
        address.setUniversity("FactoryBean");
        address.setCity("FactoryBean");
        address.setProvince("FactoryBean");
        return address;
    }

    @Override
    public Class<?> getObjectType() {
        return Address.class;
    }

    @Override
    public boolean isSingleton() {
        return false;
    }
}

配置文件中配置bean

    <bean id="address5" class="com.fiber.config.AddressFactory"/>
Bean的生命周期

Bean的生命周期分为4个阶段:
1、构造:调用类的无参构造方法。
2、依赖注入:为bean注值,会扫描@Resource,@Autowired,@Value等注解。
3、初始化:对象创建完成,并赋值好,调用初始化方法。
4、摧毁:单例模式下关闭容器时摧毁,多例模式下容器不会管理这个bean。

@Slf4j
public class LifeCycle {
    @Resource
    private AddressConfig address;

    LifeCycle(){
        log.info("构造方法");
    }
    @Autowired
    public String getJAVAHOME(@Value("${JAVA_HOME}") String s){
        log.info("执行依赖注入");
        return s;
    }
    @PostConstruct
    public void postConstructor(){
        log.info("初始化");
    }

    @PreDestroy
    public void postDestroy(){
        log.info("摧毁");
    }

    public static void main(String[] args) {
        GenericApplicationContext context = new GenericApplicationContext();
        context.registerBean("cycle",LifeCycle.class);
        context.registerBean("address",AddressConfig.class);
        //一些bean的后处理器
        //用来解析@Autowired和@Value
        context.getDefaultListableBeanFactory().setAutowireCandidateResolver(
                new ContextAnnotationAutowireCandidateResolver()
        );
        context.registerBean(AutowiredAnnotationBeanPostProcessor.class);
        //用来解析@Resource,@PostConstructor,@PreDestroy
        context.registerBean(CommonAnnotationBeanPostProcessor.class);
        context.refresh();
        context.close();
    }
}

2022-07-25 15:26:06.187 |-INFO 
            [main] com.fiber.config.LifeCycle [25] -| 构造方法
2022-07-25 15:26:06.256 |-INFO 
            [main] com.fiber.config.LifeCycle [29] -| 执行依赖注入
2022-07-25 15:26:06.256 |-INFO 
            [main] com.fiber.config.LifeCycle [34] -| 初始化
2022-07-25 15:26:06.256 |-INFO 
            [main] com.fiber.config.LifeCycle [39] -| 摧毁

3.学习Bean的作用域、Bean的注值方式

bean的作用域

  • singleton:单例,使用的对象是同一个
  • prototype:多例,每次会创建一个新的对象

Bean的注值方式

  • 通过构造器注入
    <bean id="address" class="com.fiber.pojo.Address">
        <constructor-arg index="0" value="湖北省"/>
        <constructor-arg index="1" value="武汉市"/>
        <constructor-arg index="2" value="武汉理工大学"/>
    </bean>

    <bean id="address1" class="com.fiber.pojo.Address">
        <constructor-arg name="province" value="黑龙江省"/>
        <constructor-arg name="city" value="哈尔滨市"/>
        <constructor-arg name="university" value="哈尔滨工程大学"/>
    </bean>
  • 通过set注入
    通过set构造时可以对java基本类型和引用类型进行初始化赋值。也可以使用其他的bean对象注入。
 <bean id="student1" class="com.fiber.pojo.Student">
        <property name="name" value="彭锦坤"/>
        <property name="books">
            <array>
                <value>book1</value>
                <value>book2</value>
                <value>book3</value>
            </array>
        </property>
        <property name="address" ref="address"/>
        <property name="hobby">
            <list>
                <value>hobby1</value>
                <value>hobby2</value>
                <value>hobby3</value>
            </list>
        </property>
        <property name="card">
            <map>
                <entry key="id_card" value="id_card_XXXXXXX"/>
                <entry key="student_card" value="student_card_XXXXXX"/>
            </map>
        </property>
        <property name="games">
            <set>
                <value>game1</value>
                <value>game2</value>
                <value>game3</value>
            </set>
        </property>
        <property name="wife">
            <null/>
        </property>
        <property name="info">
            <props>
                <prop key="gender">male</prop>
                <prop key="age">20</prop>
            </props>
        </property>
    </bean>
  • 自动装配
    byName:通过名称自动装配
    Student类有一个Address属性,如果属性名为address1,会查找id=address1的bean。
    <bean id="student" class="com.fiber.pojo.Student" autowire="byName"/>

byType:通过类型自动装配
会查找bean的class类型为Address 的bean,如果有多个bean类型均为Addess,会出错。

    <bean id="student" class="com.fiber.pojo.Student" autowire="byName"/>

4.注解装配Bean

1、定义bean对象的注解

  • @Component:通用的
  • @Service:用于服务层
  • @Controller:用于控制层
  • @Repository:用于DAO层

2、开启注解支持,会补充bean的后处理器。

    <context:annotation-config/>

3、扫描包里面的注解

    <context:component-scan base-package="com.fiber"/>

4、依赖注入

  • @Autowired
    只按照byType注入(可结合@Qualifier一起使用,在无法按类型匹配时按照名字匹配bean)。
  • @Resource
    默认byName注入,如果byName无法找到就通过byType查找。
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值