spring之IOC基础使用

1、原始用的手动导包的方式,不推荐使用,太麻烦

1.手动导入spring的核心jar包

2、创建对象与xml文件

package com.zcm.entity;

/**
 * @program: init-spring
 * @ClassName User
 * @Description
 * @Author zcm
 * @Date 2021/2/23 9:29
 * @Version V1.0
 */

public class User {
      private  String name;
      private String sex;
      private Integer age;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getSex() {
        return sex;
    }

    public void setSex(String sex) {
        this.sex = sex;
    }

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }

    @Override
    public String toString() {
        return "User{" +
                "name='" + name + '\'' +
                ", sex='" + sex + '\'' +
                ", age=" + age +
                '}';
    }
}
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
    <!--注册一个对象,spring回自动创建这个对象-->
    <!--
    一个bean标签就表示一个对象
    id:这个对象的唯一标识
    class:注册对象的完全限定名
    -->
    <bean id="user" class="com.zcm.entity.User">
        <!--使用property标签给对象的属性赋值
         name:表示属性的名称
         value:表示属性的值
         -->
        <property name="name" value="zhangsan"></property>
        <property name="sex" value="男"></property>
        <property name="age" value="18"></property>
    </bean>
</beans>

3.测试

package com.zcm.test;

import com.zcm.entity.*;
import org.springframework.context.*;
import org.springframework.context.support.*;

/**
 * @program: 初始springIOC控制反转
 * @ClassName Test
 * @Description
 * @Author zcm
 * @Date 2021/2/23 9:56
 * @Version V1.0
 */
public class Test {
    public static void main(String[] args) {
        //ApplicationContext:表示ioc容器
        //ClassPathXmlApplicationContext:表示从当前classpath路径中获取xml文件的配置
        //根据spring的配置文件来获取ioc容器对象
        ApplicationContext context = new ClassPathXmlApplicationContext("spring.xml");
        User bean = context.getBean("user", User.class);
        System.out.println(bean);
    }
}

2.Maven的方式构建项目

1.创建Maven项目

 定义项目artifactId,groupId

2.添加pom.xml依赖

    <properties>
        <lombok.version>1.18.10</lombok.version>
        <spring.version>5.2.3.RELEASE</spring.version>
        <logging.version>1.2</logging.version>
    </properties>

    <dependencies>
        <!--引入common-logging-->
        <dependency>
            <groupId>commons-logging</groupId>
            <artifactId>commons-logging</artifactId>
            <version>${logging.version}</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/org.springframework/spring-context -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>5.2.3.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>${lombok.version}</version>
        </dependency>
    </dependencies>

3.编写代码

package com.zcm.entity;

/**
 * @program: init-spring
 * @ClassName User
 * @Description
 * @Author zcm
 * @Date 2021/2/23 9:29
 * @Version V1.0
 */

public class User {
      private  String name;
      private String sex;
      private Integer age;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getSex() {
        return sex;
    }

    public void setSex(String sex) {
        this.sex = sex;
    }

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }

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

4.编写spring的xml文件并且给Bean对象赋值.

注意的是spring的xml文件必须放在resources文件夹下面,不然运行编译不通过,会出异常: IOException parsing XML document from class path resource [src/spring.xml]; nested exception is java.io.FileNotFoundException: class path resource [src/spring.xml] cannot be opened because it does not exist

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
    <!--注册一个对象,spring回自动创建这个对象-->
    <!--
    一个bean标签就表示一个对象
    id:这个对象的唯一标识
    class:注册对象的完全限定名
    -->
    <bean id="user" class="com.zcm.entity.User">
        <!--使用property标签给对象的属性赋值
         name:表示属性的名称
         value:表示属性的值
         -->
        <property name="name" value="zhangsan"></property>
        <property name="sex" value="男"></property>
        <property name="age" value="18"></property>
    </bean>
</beans>

5、测试

package com.zcm.test;

import com.zcm.entity.*;
import org.springframework.context.*;
import org.springframework.context.support.*;

/**
 * @program: 初始springIOC控制反转
 * @ClassName Test
 * @Description
 * @Author zcm
 * @Date 2021/2/23 9:56
 * @Version V1.0
 */
public class Test {
    public static void main(String[] args) {
        //ApplicationContext:表示ioc容器
        //ClassPathXmlApplicationContext:表示从当前classpath路径中获取xml文件的配置
        //根据spring的配置文件来获取ioc容器对象
        ApplicationContext context = new ClassPathXmlApplicationContext("spring.xml");
        User bean = context.getBean("user", User.class);
        System.out.println(bean);
    }
}

总结:

以上两种创建spring的项目都是可以的,现在企业开发中大多都用Maven仓库来构建,使用maven构建项目无需自己去处理jar之间的关系,也不需要自己下载jar,只需要添加pom配置就可以了,其他的maven都会为我们处理好。

注意:

1.导包别忘记将commons-logging-1.2.jar包导进来,不然运行会报错

2.一定要将配置文件加到类路径中,使用idea构建项目需要将配置文件加入resources文件夹下面,这个是专门用来放置配置文件的文件夹。

知识要点:

1、ApplicationContext就是IOC容器接口,可以通过此对象来获取容器中创建的对象。

2、对象是在spring容器创建的时候创建,不是在使用的时候创建的。

3.对象在IOC容器中都是单例的,需要多例需要修改Bean对象的scope="prototype"。

4.对象属性是getter、setter方法决定的,而不是成员变量。

5.创建对象属性赋值通过setter方法赋值,所以需要注意Bean属性赋值name属性需要和setter保持一致。

什么是IOC呢?

  IOC(inversion of controller)指的是控制反转,就是将创建对象的过程或者创建对象的权限交给了spring容器来帮我们管理,我们不用再通过new的方式来创建JavaBean对象,这个过程就叫做IOC。

1.spring对象的获取和使用方式?

1.通过bean的id获取IOC容器对象。

import com.zcm.spring.entity.*;
import org.springframework.context.*;
import org.springframework.context.support.*;

/**
 * @program: spring
 * @ClassName:Test
 * @Description:
 * @Author:zcm
 * @Date:2021/2/23 14:46
 */
public class Test {
    public static void main(String[] args) {
        //ApplicationContext:表示ioc容器
        //ClassPathXmlApplicationContext:表示从当前classpath路径中获取xml文件的配置
        //根据spring的配置文件Bean的id来获取ioc容器对象
        ApplicationContext context = new ClassPathXmlApplicationContext("spring.xml");
        //1.根据Bean的ID获取对象
        com.zcm.spring.entity.Person person = (Person) context.getBean("person");
        System.out.println(person);
    }
}

2.通过Bean类型获取IOC容器对象

package com.zcm.spring.test;
import com.zcm.spring.entity.*;
import org.springframework.context.*;
import org.springframework.context.support.*;

/**
 * @program: spring
 * @ClassName:Test
 * @Description:
 * @Author:zcm
 * @Date:2021/2/23 14:46
 */
public class Test {
    public static void main(String[] args) {
        //ApplicationContext:表示ioc容器
        //ClassPathXmlApplicationContext:表示从当前classpath路径中获取xml文件的配置
        //根据spring的配置文件Bean的类型来获取ioc容器对象
        ApplicationContext context = new ClassPathXmlApplicationContext("spring.xml");
        //1.根据Bean的ID获取对象
       com.zcm.spring.entity.Person person = context.getBean(Person.class);
        System.out.println(person);
}
}

注意:通过Bean的类型获取IOC容器对象,不能存在两个相同类型的Bean,否则运行会报异常

Exception in thread "main" org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type 'com.zcm.spring.entity.Person' available: expected single matching bean but found 6: person,person2,person3,person4,person5,person6

可以将两者结合使用

package com.zcm.spring.test;

import com.zcm.spring.entity.*;
import org.springframework.context.*;
import org.springframework.context.support.*;

/**
 * @program: spring
 * @ClassName:Test
 * @Description:
 * @Author:zcm
 * @Date:2021/2/23 14:46
 */
public class Test {
    public static void main(String[] args) {
        //ApplicationContext:表示ioc容器
        //ClassPathXmlApplicationContext:表示从当前classpath路径中获取xml文件的配置
        //根据spring的配置文件Bean的id来获取ioc容器对象
        ApplicationContext context = new ClassPathXmlApplicationContext("spring.xml");
        //1.根据Bean的ID获取对象
        com.zcm.spring.entity.Person person =context.getBean("person",Person.class);
        System.out.println(person);
}}

2、Spring的【DI】依赖注入

1.通过构造器给对象赋值

 <!--使用构造器赋值的时候,参数的name属性是由构造参器的参数一致的
    name:构造参数列表的名称
    value:表示实际赋值的值
    type:参数类型
    index:构造参数的位置下标,从0开始
    -->
    <bean id="person3" class="com.zcm.spring.entity.Person">
        <constructor-arg value="李四"></constructor-arg>
        <constructor-arg value="李四嗯嗯"></constructor-arg>
        <constructor-arg value="19"></constructor-arg>
        <constructor-arg value="男"></constructor-arg>
    </bean>

    <!--当通过构造器方法给对象赋值的时候,name不写,赋值的参数位置必须保持一致,如果想要位置不保持一致,可以通过index属性来限定-->
    <bean id="person2" class="com.zcm.spring.entity.Person">
        <constructor-arg  index="1" name="nickName" value="李四嗯嗯"></constructor-arg>
        <constructor-arg index="0" name="userName" value="李四"></constructor-arg>
        <constructor-arg index="2" name="age" value="18"></constructor-arg>
        <constructor-arg index="3" name="sex" value="男"></constructor-arg>
    </bean>
    <!--当构造器存在参数个数一致的情况,想要指定想要赋值的构造器,可以通过type类型来区分-->
    <bean id="person4" class="com.zcm.spring.entity.Person">
        <constructor-arg value="李四"></constructor-arg>
        <constructor-arg value="李四嗯嗯"></constructor-arg>
        <constructor-arg value="19" type="java.lang.Integer">

        </constructor-arg>
    </bean>

2.P名称空间和C名称空间

  P名称空间与C名称空间其实都是不存在的虚拟空间,主要是用于简化我们的spring为JavaBean属性赋值时的配置。

添加P名称空间与C名称空间到schema

<?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:c="http://www.springframework.org/schema/c"
       xmlns:context="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
        https://www.springframework.org/schema/context/spring-context.xsd">
    <!--    使用命名空间来为对象赋值p:XX-->
    <bean id="person5" class="com.zcm.spring.entity.Person" p:userName="123" p:sex="nv" p:age="23"
          p:nickName="231"></bean>
    <!--    使用命名空间来为对象赋值c:XX-->
    <bean class="com.zcm.spring.entity.Person" id="person13" c:userName="321" c:sex="nv" c:age="23"
          c:nickName="231"></bean>

3.通过setter方法进行赋值

    <bean id="person" class="com.zcm.spring.entity.Person">
        <!--使用property标签给对象的属性赋值
   name:表示属性的名称
   value:表示属性的值
   name属性必须和set方法后面的字段保持一致
   注意:Date类型赋值不要要用-,用/ 例如:2020-12-12 换成2020/12/12
    否则会报错nested exception is java.lang.IllegalStateException:
    Cannot convert value of type 'java.lang.String' to required type 'java.util.Date' for property 'date':
   no matching editors or conversion strategy found
   -->
        <property name="userName" value="张三"></property>
        <property name="nickName" value="校长三"></property>
        <property name="age" value="18"></property>
        <property name="sex" value="男"></property>
        <property name="date" value="2020/12/12"></property>
    </bean>

 4.SPEL表达式

  Spel表达式,类似于jstl与el表达式的语言,spring可以支持我们在为属性赋值的时候,通过spel表达式来进行更改我们的属性值。

    <!--    使用spEL表达式进行赋值-->
    <bean id="address7" class="com.zcm.spring.entity.Address">
        <property name="code" value="1001"></property>
        <property name="name" value="天津市"></property>
    </bean>
    <bean id="person14" class="com.zcm.spring.entity.Person">
        <property name="nickName" value="#{address7.name}"></property>
        <property name="userName" value="#{address7.code}"></property>
    </bean>

3.spring的【IOC】控制反转

1.使用默认的构造器创建Bean对象

<!--注册一个对象,spring会自动创建这个对象-->
    <!--
    一个bean标签就表示一个对象
    id:这个对象的唯一标识
    class:注册对象的完全限定名
    -->
    <bean id="person" class="com.zcm.spring.entity.Person"></bean>

2.利用工厂模式创建Bean对象

除了使用反射得到对象的Bean实例,在spring中还包含另外一种创建Bean实例的方式,通过工厂模式进行对象象创建,

工厂模式创建Bean实例有两种:

静态工厂:工厂本身不需要创建对象,但是可以通过静态方法调用,对象=工厂类.静态工厂方法名();

实例工厂:共产本身需要创建实例,工厂类 工厂对象=new 工厂类;工厂对象.get对象名();

静态工厂

package com.zcm.spring.entity;

import java.util.*;

/**
 * @program: demo
 * @ClassName:AddressFactory 静态工厂
 * @Description:
 * @Author:zcm
 * @Date:2021/2/24 16:32
 */

public class AddressStaticFactory {
    public static Address getNewInstant(String name) {
        Address address = new Address();
        address.setCode(1002);
        address.setName(name);
        address.setTime(new Date());
        return address;
    }
}

实例工厂

package com.zcm.spring.entity;

import lombok.*;

import java.util.*;

/**
 * @program: spring
 * @ClassName:Addres
 * @Description:
 * @Author:zcm
 * @Date:2021/2/23 17:30
 */
@Data
public class Address {
    private Integer code;
    private String name;
    private Date time;

    public void init() {
        System.out.println("Address初始化");
    }

    public void destroy() {
        System.out.println("Address被销毁");

    }

}

 实现spring的FactoryBean接口来创建Bean的实例

package com.zcm.spring.entity;

import lombok.*;

import java.util.*;

/**
 * @program: spring
 * @ClassName:Person
 * @Description:
 * @Author:zcm
 * @Date:2021/2/23 14:30
 */
@Data
public class Person {
    private String userName;
    private String nickName;
    private String sex;
    private Integer age;
    private Date date;
    private String[] strs;
    private Address address;
    private List<String> list;
    private List<Address> addressList;
    private Properties properties;

    private Set<String> sets;

    private Map<String, Object> map;


    public Person(String userName, String nickName, Integer age, String sex) {
        this.userName = userName;
        this.nickName = nickName;
        this.age = age;
        this.sex = sex;
    }

    public Person(String userName, String nickName, Integer age) {
        this.userName = userName;
        this.nickName = nickName;
        this.age = age;
        System.out.println("age.....");
    }


    public Person(String userName, String nickName, String sex) {
        this.userName = userName;
        this.nickName = nickName;
        this.sex = sex;
        System.out.println("sex.....");
    }

    public Person() {
    }


}
    <!--    利用工厂模式创建对象-->
    <!--    使用静态工厂对Bean赋值,类名.静态方法 factory-method-->
    <bean id="address3" factory-method="getNewInstant" class="com.zcm.spring.entity.AddressStaticFactory">
        <constructor-arg value="昭通市"/>
    </bean>
    <!--
    使用实例对象对Bean赋值
    实例工厂:先创建工厂实例,然后调用工厂实例的方法
    factory-bean:表示具体工厂类的实例
    factory-method:表示具体工厂的实例方法
    -->
    <bean id="addressFactory" class="com.zcm.spring.entity.AddressFactory"></bean>
    <bean id="addressStaticFactory" class="com.zcm.spring.entity.Address" factory-bean="addressFactory"
          factory-method="getNewInstant">
        <constructor-arg value="南京市"></constructor-arg>
    </bean>

 4.给复杂类型对象赋值

package com.zcm.spring.entity;

import lombok.*;

import java.util.*;

/**
 * @program: spring
 * @ClassName:Addres
 * @Description:
 * @Author:zcm
 * @Date:2021/2/23 17:30
 */
@Data
public class Address {
    private Integer code;
    private String name;
    private Date time;
}
    <bean id="address" class="com.zcm.spring.entity.Address">
        <property name="code" value="11"></property>
        <property name="name" value="福州"></property>
        <property name="time" value="2021/02/23"></property>
    </bean>
    
<bean id="person6" class="com.zcm.spring.entity.Person">
        <property name="userName" value="张三"></property>
        <property name="nickName" value="校长三"></property>
        <property name="age" value="18"></property>
        <property name="sex" value="男"></property>
        <property name="date" value="2020/12/12"></property>
        <property name="strs" value="112,113,114"></property>
        <!--        <property name="strs">-->
        <!--            <array>-->
        <!--                <value>123</value>-->
        <!--                <value>456</value>-->
        <!--                <value>789</value>-->
        <!--            </array>-->
        <!--        </property>-->
        <!--        给对象赋值,引用Bean对象addres-->
        <property name="address" ref="address"></property>
        <!--     list赋值方式一:   -->
        <!--        <property name="list" value="221,222,223"></property>-->
        <!--        list赋值方式二:-->
        <property name="list">
            <list>
                <value>00</value>
                <value>99</value>
                <value>77</value>
            </list>
        </property>
        <!--        给对象集合赋值方式一:内部Bean对象赋值-->
        <property name="addressList">
            <list>
                <bean id="address2" class="com.zcm.spring.entity.Address">
                    <property name="code" value="1002"></property>
                    <property name="name" value="上海市"></property>
                </bean>
                <!--        给对象集合赋值方式一:引用外部Bean对象赋值-->
                <ref bean="address"></ref>
            </list>
        </property>
        <!--        给set属性赋值赋值-->
        <property name="sets">
            <set>
                <value>1234</value>
                <value>5678</value>
            </set>
        </property>
        <!--        给Map赋值-->
        <property name="map">
            <map>
                <entry key="11" value="haha"></entry>
                <entry key="112" value-ref="address"></entry>
            </map>
        </property>
        <!--        <util:map id="maps">-->
        <!--            <entry key="11" value="haha"></entry>-->
        <!--            <entry key="112" value-ref="address"></entry>-->
        <!--            &lt;!&ndash;            使用内部Bean&ndash;&gt;-->
        <!--            <entry>-->
        <!--                <bean id="address3" class="com.zcm.spring.entity.Addres">-->
        <!--                    <property name="code" value="1002"></property>-->
        <!--                    <property name="name" value="上海市"></property>-->
        <!--                </bean>-->
        <!--            </entry>-->
        <!--            &lt;!&ndash;            引用外部Bean&ndash;&gt;-->
        <!--            <entry>-->
        <!--                <ref bean="address"></ref>-->
        <!--            </entry>-->
        <!--        </util:map>-->

        <!--Properties 赋值-->
        <property name="properties">
            <props>
                <prop key="123">
                    hahah
                </prop>
            </props>
        </property>
    </bean>

    <!--给级联属性赋值-->
    <bean id="person10" class="com.zcm.spring.entity.Person">
        <property name="address" ref="address"></property>
        <property name="address.name" value="北京"></property>
    </bean>

 

想要给Bean配置父类可以通过parent属性,值是bean的id属性

      <!--给级联属性赋值-->
    <bean id="person7" class="com.zcm.spring.entity.Person">
        <property name="address" ref="address"></property>
        <property name="address.name" value="北京"></property>
        <property name="nickName" value="小小小"></property>
    </bean>  
<!--    怎么配置给对象配置父类-->
    <bean id="person8" class="com.zcm.spring.entity.Person" parent="person7">
        <property name="age" value="18"></property>
        <property name="userName" value="肖小小"></property>
    </bean>

6.Bean的作用域控制,是否单例?

Bean属性scope可以声明bean的作用域范围,Bean的作用域范围有四种:

  • Prototype:多例,每次调用都会创建一个新的实例
  • Singleton:单例,创建一个对象,每次调用都是用这个对象,默认的作用域
  • Request:将对象存储在request域对象中
  • Session:将对象存储在session域对象中
    <!--
    bean的作用域:singleton、prototype、request、session
    singleton:IOC容器中的对象默认是单例的,在容器启动完成之时已经创建好对象,获取的所有的对象都是同一个。
    prototype:想要变成多例,通过scope="prototype"设置成多例,容器启动时不会创建多实例,只有获取对象的时候才会创建该对象,且每次创建的都是一个全新的对象。

Request:适用于web开发中,将我们的对象存储在request域对象中。

Session:适用于web开发中,将我们的对象存储在session域对象中。
    request、session这个只能在老版本中才有,spring5之后被淘汰了
    -->
    <bean scope="prototype" id="person9" class="com.zcm.spring.entity.Person">
        <property name="userName" value="这是一个多例对象"></property>
    </bean>

7.javaBean的生命周期

我们可以在JavaBean类中添加init-method与destroy-method两个方法,实现bean在初始化和销毁的时候调用的方法,然后在配置文件中进行配置。

package com.zcm.spring.entity;

import lombok.*;

import java.util.*;

/**
 * @program: spring
 * @ClassName:Addres
 * @Description:
 * @Author:zcm
 * @Date:2021/2/23 17:30
 */
@Data
public class Address {
    private Integer code;
    private String name;
    private Date time;

    public void init() {
        System.out.println("Address初始化");
    }

    public void destroy() {
        System.out.println("Address被销毁");

    }

}
    <!--
    spring容器在创建对象的时候可以指定初始化和销毁方法
    init-method:在对象创建完成之后会调用初始化方法
    destroy-method:在容器关闭的是会调用
    spring容器什么时候关闭呢?可以调用ClassPathXmlApplicationContext中的close方法进行关闭
    初始化和销毁的方法跟scope属性是相关联的
    如果是singleton的话初始化方法和销毁方法都是存在的
    如果prototype的话,初始化方法会调用,但是销毁的方法不会调用
     ((ClassPathXmlApplicationContext) context).close();
    -->
    <bean id="address4" class="com.zcm.spring.entity.Address" init-method="init" destroy-method="destroy">
        <property name="code" value="1009"></property>
        <property name="name" value="福州市"></property>
    </bean>

8.创建Bean的依赖关系

    <!--创建bean的时候依赖关系
    当bean对象被创建的时候,是按照xml配置文件定义的顺序创建的,谁在前,谁就先被创建
        如果需要干扰创建的顺序,可以使用depends-on属性
    一般在实际工作中不必在意bean创建的顺序,无论谁先创建,需要依赖的对象在创建完成之后都会进行赋值操作
    -->
  <bean id="address" class="com.mashibing.bean.Address" depends-on="person"></bean>
   <bean id="person" class="com.mashibing.bean.Person"></bean>

 

9.spring的Bean处理器

针对spring容器中的对象初始化的前后做出相对应的操作,spring很多对象处理器,我们只需实现BeanPostProcessor接口中的两个方法,在其中做操作就可以了。

package com.zcm.spring.entity;

import org.springframework.beans.*;
import org.springframework.beans.factory.config.*;

/**
 * @program: demo
 * @ClassName:MyBeanPostProcessor
 * @Description:
 * @Author:zcm
 * @Date:2021/2/24 17:38
 */
public class MyBeanPostProcessor implements BeanPostProcessor {
    /**
     * @Description:在每个对象初始化方法前执行 bean:具体执行的对象 beanName 执行Bean对象的id属性
     * @Author: zcm
     * @Version:v.2.7.1
     * @Date:2021/2/24 17:39
     */
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        System.out.println("postProcessBeforeInitialization:" + beanName);
        return bean;
    }

    /**
     * @Description:在每个对象初始化方后执行 bean:具体执行的对象 beanName 执行Bean对象的id属性
     * @Author: zcm
     * @Version:v.2.7.1
     * @Date:2021/2/24 17:39
     */
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        System.out.println("postProcessAfterInitialization:" + beanName);
        return bean;
    }
}

spring.xml文件中配置,必须配置不然不生效。

    <bean class="com.zcm.spring.entity.MyBeanPostProcessor" id="beanPostProcessor"></bean>

10.spring管理第三方的Bean

jdbc.properties

jdbc.username: root
jdbc.password: 123456
jdbc.url: jdbc:mysql://localhost:3306/test?serverTimezone=GMT%2B8&useUnicode=true&characterEncoding=utf-8
jdbc.driverClassName: com.mysql.cj.jdbc.Driver
        <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
            <property name="username" value="root"></property>
            <property name="password" value="123456"></property>
            <property name="url" value="jdbc:mysql://1localhost:3306/test"></property>
            <property name="driverClassName" value="com.mysql.cj.jdbc.Driver"></property>
        </bean>

在开发环境中,在配置文件中写死很不方便,大多选用配置文件的方式。引入外部的配置文件时, 需要配置context的命名空间.

xmlns:context="http://www.springframework.org/schema/context"
http://www.springframework.org/schema/context
https://www.springframework.org/schema/context/spring-context.xsd

 spring.xml

    <!--管理第三方Bean-->
    <!--    <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">-->
    <!--        <property name="username" value="root"></property>-->
    <!--        <property name="password" value="Aa123456!"></property>-->
    <!--        <property name="url" value="jdbc:mysql://192.168.0.144:3306/zx_tools_test"></property>-->
    <!--        <property name="driverClassName" value="com.mysql.cj.jdbc.Driver"></property>-->
    <!--    </bean>-->
    <!--    引入外部的配置文件 需要配置context的命名空间-->
    <context:property-placeholder location="classpath:jdbc.properties"></context:property-placeholder>
    <!--     spring容器在进行启动的时候,会读取当前系统的某些环境变量的配置,
        当前系统的用户名是用username来表示的,所以最好的方式是添加前缀来做区分
        jar版本不一致会报异常:java.sql.SQLException: com.mysql.cj.jdbc.Driver
        -->
    <bean id="druidDataSource" class="com.alibaba.druid.pool.DruidDataSource">
        <property name="username" value="${jdbc.username}"></property>
        <property name="password" value="${jdbc.password}"></property>
        <property name="url" value="${jdbc.url}"></property>
        <property name="driverClassName" value="${jdbc.driverClassName}"></property>
    </bean>

12.spring的自动装配

    <!--在spring中,可以使用自动装配的功能,spring会把某些bean注入到另外bean中
可以使用autowire属性来实现自动装配,有以下几种情况
default/no: 不装配
byName:按照id来进行装配,根据set方法后面的名称首字母小写决定的,不是参数列表的名称
byType:按照bean的类型来进行装配,但是如果有多个类型,就会报错NoUniqueBeanDefinitionException:
No qualifying bean of type 'com.zcm.spring.entity.Address' available:
expected single matching bean but found 6: address,address3,addressStaticFactory,address4,address5,address6,
不知道选择哪一个具体的类型
constructor:按照构造器进行装配,首先按照类型进行判断,如果有多个类型相同的bean,再按照id去进行判断,如果不存在构造器会赋值为null
-->
    <bean id="person10" class="com.zcm.spring.entity.Person" autowire="constructor"></bean>

13.将spring的Bean设置成抽象类

父bean不能单独实例化,因为它是不完整的,并且还被明确标记为abstract。当这样的定义很抽象时,它只能用作纯模板bean定义,用作子定义的父定义。

    <!--   将Bean对象定制成抽象类 abstract="true"-->
    <bean class="com.zcm.spring.entity.Person" id="person12" abstract="true"></bean>

14.spEL表达式

<!--SpEL表达式语法-->
    <bean id="person11" class="com.zcm.spring.entity.Person">
        <!--        引入外部Bean对象的属性-->
        <property name="userName" value="#{address.name}"></property>
        <!--可以支持运算符的所有操作-->
        <property name="age" value="#{99*2}"></property>
        <!--可以直接引入外部Bean对象 无需通过ref-->
        <property name="address" value="#{address}"></property>
        <!--可以调用静态方法-->
        <property name="sex" value="#{T(java.util.UUID).randomUUID().toString().substring(0,5)}"></property>
        <!--调用非静态方法-->
        <property name="nickName" value="#{address.getName()}"></property>
    </bean>

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值