Spring5 IOC基本操作

  • Post author:
  • Post category:其他




三.IOC基本操作(Bean管理)



3.1 Bean管理的两个操作:

1.Spring创建对象(下面是基于xml配置文件实现的)

image-20220627155124744

2.Spring注入属性



3.2 Bean管理操作的两种方式:

3.2.1 基于xml配置文件实现



1.创建对象


在配置文件中用bean标签,标签中添加对应属性,就可以完成创建

image-20220627155848737

bean标签中的常用属性

id:表示唯一标识

class:包类路径

创建对象时,默认使用无参构造方法进行对象的创建,如果定义了有参构造器,那么就会报错



2.注入属性


需要在Book类中为属性创建set方法

DI:依赖注入,


要注意在注入属性之前要先创建对象

Book类:

/**
 * 输出书名和作者
 */
public class Book {
    private String bookName;
    private String bookAuthor;

    public void setBookName(String bookName) {
        this.bookName = bookName;
    }

    public void setBookAuthor(String bookAuthor) {
        this.bookAuthor = bookAuthor;
    }

    public void testDemo(){
        System.out.println(bookName);
        System.out.println(bookAuthor);
    }

xml文件:

<!--    book类中的属性注入-->
    <bean id="book" class="com.ccw.spring5.day02.Book">
<!--   使用property标签完成属性注入   -->
<!--   name:属性名 -->
<!--   value:属性注入的值 -->
        <property name="bookName" value="英雄联盟"></property>
        <property name="bookAuthor" value="拳头公司"></property>
    </bean>

测试类:

@Test
public void testBook(){
    //1.加载spring的配置文件
    ApplicationContext context =
            new ClassPathXmlApplicationContext("bean1.xml");

    //2.获取配置创建的对象
    Book book = context.getBean("book",Book.class);
    book.testDemo();
}

当类中使用了有参构造器如何注入:

<!--    book类中的属性注入-->
    <bean id="book" class="com.ccw.spring5.day02.Book">
    <!--        在使用有参构造器的时候要使用constructor-arg标签来注入-->
        <constructor-arg name="bookName" value="英雄联盟"></constructor-arg>
        <constructor-arg name="bookAuthor" value="拳头公司"></constructor-arg>
    </bean>
/**
 * 输出书名和作者
 */
public class Book {
    private String bookName;
    private String bookAuthor;

    public Book(String bookName, String bookAuthor) {
        this.bookName = bookName;
        this.bookAuthor = bookAuthor;
    }

    public void testDemo(){
        System.out.println(bookName);
        System.out.println(bookAuthor);
    }
}


3.xml注入其他类型属性

null值:

<property name="address">
 <null/>
</property>
<constructor-arg name="address"><null/></constructor-arg>

特殊符号:

例如《南京》:把带符号的内容写到CDATA中,

直接输入CD就有了

<property name="address">
         <value><![CDATA[《南京》]]></value>
     </property>y>


4.外部注入bean
public class UserService {
    //创建UserDao类型属性,生成set方法
    private UserDao userDao;

    public void setUserDao(UserDao userDao) {
        this.userDao = userDao;
    }

    public void add(){
        System.out.println("service add......");
        userDao.update();

    }
}

dao接口

public interface UserDao {
    public void update();
}

dao接口实现类

public class UserDaoImpl implements UserDao {
    @Override
    public void update() {
        System.out.println("dao update......");
    }
}

xml文件

 <bean id="UserServic" class="com.ccw.spring5.day03.service.UserService">
        <!-- ref:创建userDao对象bean标签id值       -->
        <property name="userDao" ref="UserDao"></property>
    </bean>
    <bean id="UserDao" class="com.ccw.spring5.day03.dao.UserDaoImpl"></bean>
</beans>

测试方法:

public class TestBean {
    @Test
    public void testBean(){
        ApplicationContext context = new ClassPathXmlApplicationContext("bean2.xml");
        UserService userService = context.getBean("userService",UserService.class);
        userService.add();
    }
}


5.内部注入bean

实体类:

//部门类
public class Department {
    private String name;

    public void setName(String name) {
        this.name = name;
    }
}
 @Override
    public String toString() {
        return "Department{" +
                "name='" + name + '\'' +
                '}';
    }



//员工类
public class Employee {
    private String name;
    private String gender;//性别
    private Department dept;//员工部门

    public void setDept(Department dept) {
        this.dept = dept;
    }

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

    public void setGender(String gender) {
        this.gender = gender;
    }
}

xml文件:

<bean name="Employee" class="com.ccw.spring5.day04.Employee">
    <property name="name" value="ccw"></property>
    <property name="gender" value=""></property>
    <property name="dept">
        <bean name="Department" class="com.ccw.spring5.day04.Department">
            <property name="name" value="安保部"></property>
        </bean>
    </property>
</bean>


6.级联赋值

xml文件:

(方式1):

<bean name="employee" class="com.ccw.spring5.day04.Employee">
    <property name="name" value="ccw"></property>
    <property name="gender" value="男"></property>
   <property name="dept" ref="Department"></property>
</bean>
<bean name="Department" class="com.ccw.spring5.day04.Department">
    <property name="name" value="安保部"></property>
</bean>

(方式二):

此方式需要在实体类中添加get方法

image-20220702000002517

<bean name="employee" class="com.ccw.spring5.day04.Employee">
    <property name="name" value="ccw"></property>
    <property name="gender" value=""></property>
   <property name="dept" ref="Department"></property>
    <property name="dept.name" value="财务部"></property>
</bean>
<bean name="Department" class="com.ccw.spring5.day04.Department">
</bean>


7.注入集合类型属性

(1)注入数组类型

(2)注入List集合类型属性

(3)注入Map集合类型属性

  <bean name="student" class="com.ccw.spring5.day05.Student">
<!--        数组类型属性,property中可以用array,也可以用list   -->
        <property name="courses">
            <array>
                <value>语文</value>
                <value>java</value>
            </array>
        </property>
        
<!--        list类型属性    -->
        <property name="list">
            <list>
                <value>张三</value>
                <value>李四</value>
            </list>
        </property>
        
<!--        Map类型属性  entry标签来表示key和value-->
        <property name="map">
            <map>
                <entry key="JAVA" value="java"></entry>
                <entry key="PYTHON" value="python"></entry>
            </map>
        </property>
        
<!--        set类型属性-->
        <property name="set">
            <set>
                <value>100</value>
                <value>50</value>
            </set>
        </property>

    </bean>

Student类:

public class Student {
    //1.数组类型属性
    private String[] courses;//课程

    //2.list集合类型属性
    private List<String> list;

    //3.Map集合类型属性
    private Map<String,String> map;

    //4.set集合类型属性
    private Set<String> set;

    public void setCourses(String[] courses) {
        this.courses = courses;
    }

    public void setList(List<String> list) {
        this.list = list;
    }

    public void setMap(Map<String, String> map) {
        this.map = map;
    }

    public void setSet(Set<String> set) {
        this.set = set;
    }
}


8.在集合里面设置对象类型值
  <bean id="student" class="com.ccw.spring5.day05.Student">
      
<!--        注入List集合类型,值是对象     -->
        <property name="courseList">
            <list>
                <ref bean="course1"></ref>
                <ref bean="course2"></ref>
            </list>
        </property>
    </bean>

<!--    创建多个course对象        -->
    <bean id="course1" class="com.ccw.spring5.day05.Course">
        <property name="name" value="Spring5"></property>
    </bean>
    <bean id="course2" class="com.ccw.spring5.day05.Course">
        <property name="name" value="SpringBoot"></property>
    </bean>


9.集合注入部分共用


需要在Spring配置文件中引入名称空间util

<?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:util="http://www.springframework.org/schema/util"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
                           http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd">

</beans>


使用util标签完成List集合注入提取

<!--    提取list集合属性注入(公共部分)-->
    <util:list id="bookList">
        <value>唐诗三百首</value>
        <value>伊索寓言</value>
        <value>睡前故事</value>
    </util:list>

<!--    公共部分的使用     -->
    <bean id="book" class="com.ccw.spring5.day05.Book">
        <property name="list" ref="bookList"></property>
    </bean>

Book类:

public class Book {
    private List<String> list;

    public void setList(List<String> list) {
        this.list = list;
    }

    public void add(){
        System.out.println(list);
    }
}


10. Bean的两种类型


分为普通bean工厂bean(FactoryBean)

普通bean:class中的类就是返回值的类型

image-20220703111435780
image-20220703111645519

工厂bean:配置文件定义的bean类型和返回值类型可以不同

步骤:

1.创建类,让这个类作为工厂bean,实现接口FactoryBean

2.实现接口中的方法,在实现的方法中定义返回的bean类型

public class MyBean implements FactoryBean<Course> {//添加泛型为需要的类型

    //定义返回bean的类型
    @Override
    public Course getObject() throws Exception {
        Course course = new Course();
        course.setName("adc");
        return course;
    }
<!--bean中为工厂类的类名-->
<bean id="myBean" class="com.ccw.spring5.day06.MyBean"></bean>
//测试类中对应的地方也应进行修改
public void test(){
    ApplicationContext context = new ClassPathXmlApplicationContext("BeanXml/day06/bean6.xml");
    Course course = context.getBean(/*这里需要填写bean中的id名称*/"myBean",Course.class);
    System.out.println(course);
}


11.bean作用域

在spring中,设置创建bean实例是单实例还是多实例(

默认为单实例

image-20220704130326324

无论创建多少个对象,都表示同一个地址


那么如何设置多实例呢?

可以在spring配置文件中的bean标签里面的

scope

用来设置

scope两个主要的属性值:

singleton:表示单实例对象(默认值)

prototype:表示多实例对象

image-20220704130844037

image-20220704130852506

在bean标签中加入scope属性,那么就变成了多例



两者区别:

当scope为singleton时,在加载spring配置文件时就会创建单实例对象

当scope为prototype时,在调用getbean方法的时候创建多实例对象,而不是在配置spring文件的时候



12.bean的生命周期

什么叫bean生命周期:从对象创建到对象销毁的过程

bean生命周期步骤:

(1)通过构造器创建bean实例(无参数构造)

(2)为bean的属性设置值和对其他bean引用(调用set方法)

(3)调用bean的初始化的方法(需要进行配置初始化的方法)

需要在spring文件中进行添加

image-20220705170012250

(4) bean可以使用了(对象获取到了)

(5)当容器关闭时候,调用bean的销毁的方法(需要进行配置销毁的方法)

代码如下:

public class Order {
    private String name;

    //第一步 执行无参构造器创建bean实例
    public Order() {
        System.out.println("第一步 执行无参构造器创建bean实例");
    }

    //第二步 调用set方法设置属性值
    public void setName(String name) {
        this.name = name;
        System.out.println("第二步 调用set方法设置属性值");
    }

    //第三步 创建执行初始化的方法
    public void initMethod(){
        System.out.println("第三步 创建执行初始化的方法");
    }

    //第四步 获取创建bean实例对象(写在测试方法中,这里为了方便写在order类中)
    @Test
    public void test(){
        ApplicationContext context = new ClassPathXmlApplicationContext("BeanXml/day07/bean7.xml");
        Order order = context.getBean("order",Order.class);
        System.out.println(order);
        System.out.println("第四步 获取创建bean实例对象");

        //手动销毁bean
        ((ClassPathXmlApplicationContext)context).close();
    }

    //第五步 执行销毁的方法
    public void destroyMethod(){
        System.out.println("第五步 创建执行销毁的方法");
    }


}

xml文件代码如下:

<bean id="order" class="com.ccw.spring5.day07.Order"
      init-method="initMethod" destroy-method="destroyMethod">
    <property name="name" value="手机"></property>
</bean>


后置处理器

也是bean生命周期的步骤,添加进入的顺序为:(添加后为7步)

(1)通过构造器创建bean实例(无参数构造)

(2)为bean的属性设置值和对其他bean引用(调用set方法)


(3) 把bean实例传递bean后置处理器的方法(postProcessBeforeInitialization)

(4)调用bean的初始化的方法(需要进行配置初始化的方法)


(5) 把bean实例传递bean后置处理器的方法(postProcessAfterInitialization)

(6) bean可以使用了(对象获取到了)

(7)当容器关闭时候,调用bean的销毁的方法(需要进行配置销毁的方法)



13.自动装配(自动注入属性)

根据指定装配规则(属性名称或者属性类型),Spring自动将匹配的属性值进行注

<!--
    实现自动装配:
    bean标签中的autowire,配置自动装配
    autowire两个常用属性:
        ①:byName:根据属性名称注入
        ②:byType:根据属性类型注入
  -->
<!--   根据名称     -->
    <bean id="employee" class="com.ccw.spring5.day08.Employee" autowire="byName"></bean>
    <bean id="dept"  class="com.ccw.spring5.day08.Department"></bean><!--注入的值要与实现类中属性名称相同 -->
    <!--   根据类型     -->
    <bean id="employee" class="com.ccw.spring5.day08.Employee" autowire="byType"></bean>
    <bean id="dept"  class="com.ccw.spring5.day08.Department"></bean>
<!--    <bean id="dept1"  class="com.ccw.spring5.day08.Department"></bean>
使用byType时,相同类型的bean只能定义一个-->


14.引入外部属性文件(等之后理解)



3.2.2 基于注解方式实现



1.注解详解

1.注解是代码特殊标记,格式:@注解名称(属性名称=属性值,属性名称=属性值)

2.使用注解时,可以在类上面,方法上面,属性上面

3.使用注解目的:简化xml文件



2.创建对象


分为四种:四种功能相同都可以用来创建bean实例,一般用在对应的地方

@Component(皆可) @Service(业务层,service层) @Controller(web层) @Repository(dao层)

步骤:

1.引入依赖
image-20220722172851027

2.开启组件扫描

两种方式:1.如果想扫描多个包中的内容,多个包之间只用逗号隔开

2.扫描包的上层目录

3.创建类,类上面添加注解(注解中的value可以不写,默认为类名首字母小写)

<?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: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  http://www.springframework.org/schema/context/spring-context.xsd" >

<!--    开启组件扫描-->
<context:component-scan base-package="com.ccw.annotation.day01"></context:component-scan>
</beans>

组件扫描的两种特殊方式:

<!--    开启组件扫描-->
<!--方式一 :包含类型为......-->
<context:component-scan base-package="com.ccw.annotation.day01" use-default-filters="false"><!--use-default-filters表示是否需要全部扫描-->
    <context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
</context:component-scan>
<!--方式二:不包含类型为......-->
    <context:component-scan base-package="com.ccw.annotation.day01" >
        <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
    </context:component-scan>


3.属性注入

常用四种:

@Autowired:根据属性类型进行自动装配

@Qualifier:根据属性名称进行注入,

要和@Autowired一起使用


若@Autowired指明某个接口,但是此接口有多个实现类,那么就需要使用@Qualifier来进行指明

//定义Dao类型属性
//不需要添加set方法,注解自带
@Autowired
@Qualifier(value = "userDaoImpl2")
private UserDao userDao;

@Resource:可以根据类型注入,可以根据名称注入,

括号中的属性为name

@Value:注入普通类型属性

例如String类型

@Value(value = "ccw")//注入属性的值
private String name;


4.完全注解开发

1.创建配置类(xml就可以删除了)

@Configuration  //作为配置替换xml配置文件
@ComponentScan(basePackages = {"com.ccw.annotation"})
//相当于xml中的<context:component-scan base-package="com.ccw.annotation" >
public class SpringConfig {
}

2.编写测试类(相当于把以前的测试代码中的 ClassPathXmlApplicationContext 改成AnnotationConfigApplicationContext 其余不变)

public void test(){
    //加载配置类
    ApplicationContext context =
            new AnnotationConfigApplicationContext(SpringConfig.class);
    UserService userService = context.getBean("userService",UserService.class);
    userService.add();
}



版权声明:本文为qq_65201998原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。