Spring入门(从xml开始理解本质到注解开发)

基于xml的Spring应用

SpringBean的配置详解

  • Bean的id(后期会自动转化为name)和全限定名配置

    不配置id之时会默认将class的路径名作为id后期再转化为name

    <bean id="" class="">  
  • 通过name设置Bean的别名

    getBean(name)
    name="name1 [,name2,...]"设置的是别名,使用逗号分隔多个别名

    <bean name="">  
  • Bean的作用范围

    当BeanFactory作为容器时为singleton/prototype

    singleton(默认值):单例,Spring容器创建之时,便会进行Bean的实例化,并存储到容器内部的单例池,每次使用getBean都会从单例池中获取相同的Bean实例;

    singletonObjects:单例池

    prototype:原型,Spring容器初始化时不创建Bean实例,每次使用getBean时都会创建一个全新的Bean实例

    <bean scope="">  
  • Bean的实例化时机,是否延迟加载(本质是单例的)

    当BeanFactory作为容器时无效

    <bean lazy-init="true">  
  • Bean实例化后自动执行的初始化方法,method指定方法名

    <bean init-method="">  
  • Bean实例销毁前自动执行的方法,method指定方法名

    <bean destroy-method="">  
  • 设置自动注入模式
    byName:

        <bean id="userService" class="com.xiaowan.service.Impl.UserServiceImpl" autowire="byName">  
        </bean>      <bean id="userDao" class="com.xiaowan.dao.impl.UserDaoImpl">  
        </bean>  ```  名字一定要对应上,例如上面的Bean类userDao的name为userDao则在UserServiceImpl中设置userDao的方法一定得为:setUserDao,即set+(首位大写)Bean类id/name  
    
    btType:  
      可以忽略名字进行类型匹配,但只能一个类型的Bean配置只能有一个  

常用的有:

  • byType

  • byName

<bean autowrie="">  
  • 指定哪个工厂Bean的哪个方法完成Bean的创建

    <bean factory-bean="" factory-method=""/>  

    Spring Bean的实例化配置

本身整体使用的即为工厂模式,以下描述的是工厂模式在制造bean的时候用到的方式(构造方法或者嵌套工厂模式)

Spring实例化方式:

  • 构造方式实例化:底层通过构造方法对Bean进行实例化

    <bean id="userDao" class="com.xiaowan.dao.impl.UserDaoImpl"/>  
    ```  以上方式即为默认的无参构造方法实例化Bean  
    
    为UserDaoImpl添加有参构造:  
    ```java  
        public UserServiceImpl(String name) {  
            System.out.println("UserServiceImpl有参构造,接收参数name:"+name);  
        }  
    ```  xml更改为有参构造并传参  
    ```xml  
    <bean id="userService" class="com.xiaowan.service.Impl.UserServiceImpl">  
       <constructor-arg name="name" value="123">  
       </constructor-arg>     <property name="userDao" ref="userDao">  
       </property>  </bean>  
    ```  > 该方法不常用  
    > <b style="color:red">constructor-arg可以在bean创造时所需要传参的地方都能使用</b>  
  • 工厂方式实例化:底层通过调用自定义的工厂方法对Bean进行实例化

    • 静态工厂方法实例化Bean

      使用自定义工厂中的静态方法的内部产生Bean,并将其交予Spring容器管理

      即调用方法时无需产生类对象,直接通过类访问进行调用方法实例化bean  
      public class MyBeanFactory1 {  
      public static UserDao userDao(){  
              return new UserDaoImpl();  
          }  
      }  
      ```        ```xml  
      <bean id="userDao1" class="com.xiaowan.factory.MyBeanFactory1" factory-method="userDao">  
      </bean>    ```    **Bean实例化过程中无需实例化MyBeanFactory1直接配置类中实例化UserDaoImpl的方法userDao()即可完成Spring容器托管**  
      该方法的优点:  
      - Bean创建之前可以进行一些其他的业务逻辑操作  
      - 方便将第三方Bean交予Spring容器托管  
              如jdbc中Connection类便是通过DrivenManager.getConnection()方法进行实例化,这里便可以通过静态工厂对Connection进行Spring容器托管  
  • 实例工厂方法实例化Bean

    在工厂中的非静态方法中产生的返回值为Bean,并交予Spring容器管理
    即必须实例化工厂类对象,才能访问方法进行Bean的实例化

    public class MyBeanFactory2 {  
    public UserDao userDao(){  
            return new UserDaoImpl();  
        }  
    }  
    ```    ```xml  
    <bean id="myBeanFactory2" class="com.xiaowan.factory.MyBeanFactory2">  
    </bean>  <bean id="userDao2" factory-bean="myBeanFactory2" factory-method="userDao">  
    </bean>  ```  **Bean实例化时需要先实例化工厂对象MyBeanFactory2才能调用方法进行Bean的实例化,且配置时需要先声明工厂类,并在Bean配置中使用factory-bean映射对应的工厂类实例,再通过factory-method中配置的方法的返回对象实例化Bean**  
    > 当以上两种方法实现有参数的方法时使用constructor-arg配置参数  
    > 当配置了factory-method后则实例化的Bean对象为factory-method所指定的方法的返回的Bean对象  
  • 实现FactoryBean规范延迟实例化Bean

    当Bean需要被使用时才会实例化(原先为Spring容器被创建时则在单例池中立马进行Bean实例化),即为延迟实例化,在该过程中,单例池中所实例化的对象为包含对应方法的工厂类,而Bean需要准备使用时(执行getBean()时),Bean的实例化会发生在工厂单例缓存池中(factoryBeanObjectCache)进行实例化并调取

    public class MyBeanFactory3 implements FactoryBean<UserDao> {  
        @Override  
        public UserDao getObject() throws Exception {  
            return new UserDaoImpl();  
        }  
        @Override  
        public Class<?> getObjectType() {  
            return UserDao.class;  
        }  
    }  
    ```    ```xml  
    <bean id="userDao3" class="com.xiaowan.factory.MyBeanFactory3">  
    </bean>  ```  配置中实例化的并不是com.xiaowan.factory.MyBeanFactory3的对象,而是getObject()中返回的对象,类似与factory-method="getObject"  
    
    > 在底层中常用该方式  
  • Bean的依赖注入配置

    ref:用于注入引用对象,且该引用对象在配置文件中已进行配置(即容器中的某一个Bean注入容器中的另外一个Bean)

    value:用于注入普通属性
    set方法注入:

    <property name="userDao" ref="userDao"></property>  
    ```  >   
    构造Bean方法注入:  
    
    ```xml  
    <constructor-arg name="name" value="123"></constructor-arg>  
    ```  集合属性注入:例如List、Map、Properties等  
    • List

      list内为普通对象:

          private List<String> stringList;  
      
          public void setStringList(List<String> stringList) {  
              this.stringList = stringList;  
          }  
      
          //用于遍历list  
          @Override  
          public void showList(){  
              stringList.forEach(System.out::println);  
          }  
      ```        ```xml  
          <bean id="userServiceList" class="com.xiaowan.service.Impl.UserServiceImpl">  
              <property name="stringList">  
                  <list>  
                      <value>aaa</value>  
                      <value>bbb</value>  
                  </list>  
              </property>  
          </bean>  
      ```    list内为引用对象  
      ```java  
      private List<UserDao> userDaoList;  
      
          public void setUserDaoList(List<UserDao> userDao) {  
              this.userDaoList = userDao;  
          }  
      ```        ```xml  
          <bean id="userServiceList" class="com.xiaowan.service.Impl.UserServiceImpl">  
              <property name="userDaoList">  
                  <list>  
                      <bean class="com.xiaowan.dao.impl.UserDaoImpl">  
                      </bean>                </list>  
              </property>   
      </bean>  
      三种getBean方法:
方法定义返回值和参数前提条件
Object getBean(String beanName)根据beanName从容器获取Bean实例,返回值为Object,需要强转容器中Bean唯一
T getBean(Class type)根据Class类型从容器中获取Bean实例,返回值为Class类型实例容器中Bean类型唯一
T getBean(String beanName,Class type)根据beanName从容器获取Bean实例,返回值为Class类型实例

配置非自定义的Bean

非自定义Bean:第三方jar包

明确两点:

  • 被配置的Bean的实例化方式时什么(无参构造、有参构造、静态工厂还是实例工厂等)

  • 被配置的Bean是否需要注入必要属性

例1-Druid数据源的配置:

导入Druid坐标

    <dependency>  
      <groupId>com.alibaba</groupId>  
      <artifactId>druid</artifactId>  
      <version>1.2.18</version>  
    </dependency>  

不交于Spring容器管理的写法(传统写法):

        DruidDataSource dataSource = new DruidDataSource();  
        dataSource.setDriverClassName("");  
        dataSource.setUrl("");  
        dataSource.setUsername("");  
        dataSource.setPassword("");  

交予Spring容器管理写法:

  1. 判断Bean的实例化方式
    查看源码是否有构造方法(有参、无参)
    该源码存在无参构造

    该Bean需要注入必要属性

    public void setDriverClassName(String driverClassName) { 
    this.driverClassName = driverClassName; 
    }
    public DruidDataSource() {  
           this(false);  
       }   
  2. 根据set方法的命名规则设置参数配置

       <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">  
           <property name="driverClassName" value=""> </property>  
           <property name="url" value=""> </property>  
           <property name="username" value=""> </property>  
           <property name="password" value=""> </property>  
       </bean>  

    配置完毕

例2-JDBC:Connection的配置

导入connection的坐标

    <dependency>  
      <groupId>mysql</groupId>  
      <artifactId>mysql-connector-java</artifactId>  
      <version>8.0.33</version>  
    </dependency>  

传统写法:

Class.forName("");  
Connection connection = DriverManager.getConnection("");  

交予Spring容器管理写法:

  1. 查看Bean实例化方式
    该源码为接口,无无参构造
    Connection为静态工厂方式进行实例化,由DriverManager作为静态工厂通过静态方法进行实例化
    该Bean需要注入的必要属性名称

       @CallerSensitive  
       public static Class<?> forName(String className)  
                   throws ClassNotFoundException {  
           Class<?> caller = Reflection.getCallerClass();  
           return forName0(className, true, ClassLoader.getClassLoader(caller), caller);  
       }  
  2. 配置

       <bean id="clazz" class="java.lang.Class" factory-method="forName">  
           <constructor-arg name="className" value=""> </constructor-arg>  
       </bean>  
       <bean id="connection" class="java.sql.Connection" factory-method="getConnection">  
           <constructor-arg name="url" value=""></constructor-arg>  
           <constructor-arg name="user" value=""></constructor-arg>  
           <constructor-arg name="password" value=""></constructor-arg>  
       </bean>  
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值