zoukankan      html  css  js  c++  java
  • Spring(IOC部分)

    首先spring是一个企业级J2EE的框架,用于开发一个webApp,它是针对bean的生命周期进行管理的轻量级容器。主要由七个部分组成:Spring Core、Spring AOP、Spring ORM、Spring DAO、Spring Context、Spring Web、Spring Web MVC

    它有两大特性IOCAOP

    IOC是什么?

    基本概念

    1.IOC容器是一个创建对象、配置对象、连接对象、并管理对象的生命周期的一个容器,这里的对象即bean对象。

    2.bean 是一个被实例化,组装,并通过IOC容器所管理的对象。

    实现IOC容器的两种方式:

    (1) BeanFactory

    • Spring内部使用,开发人员基本不用,加载配置文件时不会创建对象,使用时才会创建对象。

    (2) ApplicationContext

    • BeanFactory的子接口,在其基础上添加更多功能,加载配置文件时就创建了好配置的对象。

    基于XML管理Bean

    DI:依赖注入,即注入属性

    注入普通属性

    <!--调用无参构造函数,使用set方法注入属性-->
    <bean id="user" class="di.pojo.User">
        <property name="password" value="12345"/>
        <property name="username">
            <null/>  <!--设置为null-->
        </property>
    </bean>
    
    <!--调用有参构造函数注入属性-->
    <bean id="user1" class="di.pojo.User">
        <constructor-arg name="password" value="67890"/>
        <constructor-arg name="username">
            <null/>
        </constructor-arg>
    </bean>
    

    注入引用对象属性

    当一个对象中含有另一个对象的引用,可通过引用外部bean、内部bean、级联三种方式设置引用对象的属性:

    <!--引入外部bean赋值-->
    <bean id="bookImpl" class="di.dao.impl.BookImpl">
        <property name="bookName" value="红楼梦"/>
    </bean>
    
    <bean id="bookService" class="di.service.BookService">
        <property name="bookDao" ref="bookImpl"/>  <!--调用BookService中的setBookDao-->
    </bean>
    
    <!--引入内部bean赋值-->
    <bean id="bookService1" class="di.service.BookService">
        <property name="bookDao">
            <bean class="di.dao.impl.BookImpl">
                <property name="bookName" value="水浒传"/>
            </bean>
        </property>
    </bean>
    
    <!--级联属性赋值-->
    <bean id="bookService2" class="di.service.BookService">
        <property name="bookImpl" ref="bookImpl"/>  <!--这行有必要-->
        <property name="bookImpl.bookName" value="三国演义"/>
    </bean>
    

    注入集合属性

    <!--注入集合属性-->
    <bean id="collection" class="di.pojo.Collection">
        <property name="arr">
            <array>
                <value>arr1</value>
                <value>arr2</value>
            </array>
        </property>
        <property name="list">
            <list>
                <value>list1</value>
                <value>list2</value>
            </list>
        </property>
    
        <!--引用外部bean,添加到List<User>集合中-->
        <property name="userList">
            <list>
                <ref bean="user"/>
                <ref bean="user1"/>
            </list>
        </property>
    
    
        <property name="set">
            <set>
                <value>set1</value>
                <value>set2</value>
            </set>
        </property>
        <property name="map">
            <map>
                <entry key="key1" value="value1"/>
                <entry key="key2" value="value2"/>
            </map>
        </property>
    </bean>
    

    普通bean和工厂bean的区别

    IOC有两种bean,一种是普通bean,配置文件中定义的class类型和在代码中获取的类型必须要一致,上面配置的所有bean都是普通bean;另外一种是工厂bean,即配置文件定义的类型和返回的类型可以不一致,其类必须实现FactoryBean接口,如下:

    public class FactoryBeanTest implements FactoryBean<User> {
        @Override
        public User getObject() throws Exception {
            return new User("factory", "111111");
        }
    
        @Override
        public Class<?> getObjectType() {
            return null;
        }
    
        @Override
        public boolean isSingleton() {
            return false;
        }
    }
    

    相应bean配置如下(注意,这里配置的类型为FactoryBeanTest):

    <!--工厂bean-->
    <bean id="factoryBean" class="di.pojo.FactoryBeanTest"/>
    

    相应单元测试如下(注意,这里返回的类型为User)

    @Test
    public void demo7() {
        User user = context.getBean("factoryBean", User.class);
        System.out.println(user);
    }
    

    bean作用域

    创建bean配置的对象是否为单例,默认为单例。

    可以通过设置bean标签的scope,设置创建的对象是否为单例

    prototype 非单例

    singleton 单例

    <bean id="user" class="di.pojo.User" scope="prototype"/>
    

    bean生命周期

    生命周期:

    一个对象从创建到销毁的周期

    bean的生命周期

    1.调用构造方法构造对象

    2.调用set方法设置属性

    3.将对象传入后置处理器重写的postProcessBeforeInitialization方法

    4.调用xml配置的初始化方法

    5..将对象传入后置处理器重写的postProcessAfterInitialization方法

    6.真正使用对象

    7.销毁对象,通过ClassPathXmlApplicationContext的close方法销毁,销毁时会调用xml配置的注销方法

    <!--演示bean的生命周期-->
    <bean id="beanLifeCycle" class="di.pojo.lifecycle.BeanLifeCycle" init-method="init" destroy-method="destroy">
        <property name="str" value="nothing"/>
    </bean>
    
    <!--配置后置处理器-->
    <bean id="myPostProcessor" class="di.pojo.lifecycle.LifeOfPostProcessor"/>
    

    后置处理器类

    public class LifeOfPostProcessor  implements BeanPostProcessor {
        // 所有配置的bean都会调用这里
        @Override
        public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
            System.out.println("第三步:调用初始化方法之前" + beanName);
            return bean;
        }
    
        @Override
        public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
            System.out.println("第五步:调用初始化方法之后" + beanName);
            return bean;
        }
    }
    

    基于注解管理bean

    使用注解创建bean对象

    @Component :通用标识bean对象的注解

    @Service:标识业务层的bean对象的注解(Service层)

    @Controller:标识控制器层的bean对象的注解(Web层)

    @Repository:标识数据持久层的bean对象的注解(Dao层或者说Mapper层)

    *这四个注解都可以标识一个bean,使其可以让IOC容器管理,但通常用不同的注解标识不同的层,更好区分。

    // 默认值以类的首字母小写,相当于<bean id="components" class="di.component.Components"/>
    @Component(value = "components")
    public class Components {
        public void simple(){
            System.out.println("Components simple function");
        }
    }
    

    使用注解注入属性

    @Autowired 通过类型注入属性

    @Qualifier 通过名称注入属性,必须和@Autowired配合使用

    @Resource 通过类型或者名称注入属性,位于javax.annotation.Resource,并不属于spring框架

    @Value 注入普通类型属性

    例如:

    @Service(value = "userService")
    public class UserService {
        @Autowired  // 通过类型输入属性
        @Qualifier("userImpl2")  // 如果UserDao接口有多个实现类,就需要该注解通过名称注入属性了
        private UserDao userDao;
    
        @Value(value = "8080")
        private String port;
        
    //  @Resource   位于javax.annotation.Resource,但是现在不见了。。。。
        public void simple(){
            System.out.println("UserService simple function");
        }
        public void userDaoMethod(){
            System.out.println("port:" + port);
            System.out.println("userDao.simple:");
            userDao.simple();
        }
    }
    

    当然仅仅是有注解还不行,spring并不知道哪些是需要管理的bean,所以需要配置,配置的方法有两种,一种是基于xml配置,一种是基于注解@Configuration配置

    基于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:contex="http://www.springframework.org/schema/context"
           xsi:schemaLocation="http://www.springframework.org/schema/beans
            http://www.springframework.org/schema/beans/spring-beans.xsd
            http://www.springframework.org/schema/context
            http://www.springframework.org/schema/context/spring-context.xsd">
    
        <!--扫描ioc包下所有的注解-->
        <contex:component-scan base-package="ioc">
        </contex:component-scan>
    
    </beans>
    

    基于注解@Configuration配置

    //完全注解开发,不依赖xml配置文件
    @Configuration
    @ComponentScan(basePackages = "ioc")
    public class SpringConfig {
    }
    
  • 相关阅读:
    区别是否是 微信浏览器 ?
    添加收藏
    函数调用那点事
    移动端返回上一页,刚需!document.referrer 详解
    蓝桥杯-乘积尾零
    printf不能直接输出string类型
    bitset的简单用法
    to_string()函数(C++)
    蓝桥杯-明码
    手写C语言字符库
  • 原文地址:https://www.cnblogs.com/main404/p/13235987.html
Copyright © 2011-2022 走看看