您现在的位置是:首页 >技术杂谈 >Spring:Bean的实例化(构造方法、静态工厂和实例化工厂)网站首页技术杂谈

Spring:Bean的实例化(构造方法、静态工厂和实例化工厂)

坚持不懈的大白 2023-07-08 04:00:03
简介Spring:Bean的实例化(构造方法、静态工厂和实例化工厂)

三种方式,分别为构造方法、静态工厂和实例化工厂

新建Module项目,选择Maven,在pom.xml导入如下依赖:
pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>org.example</groupId>
    <artifactId>spring-1</artifactId>
    <version>1.0-SNAPSHOT</version>

    <dependencies>

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>5.2.22.RELEASE</version>
        </dependency>

        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
            <scope>test</scope>
        </dependency>
    </dependencies>
</project>

1. 构造方法

如下:有一个接口BookDao和其实现类BookDaoImpl,怎样在外部类上不使用new创建实例来使用其下的save方法。
BookDao

package com.bh.dao;

public interface BookDao {
    void save();
}

BookDaoImpl

package com.bh.dao.Impl;

import com.bh.dao.BookDao;

public class BookDaoImpl implements BookDao {

    public void save() {
        System.out.println("数据已保存!");
    }
}

在当前项目的resources文件夹下新建applicationContext.xml文件,在这个文件里添加如下配置bean即可。
请添加图片描述

<?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">

<!--
bean 标签表示配置bean
id属性表示给bean起名字
class属性表示给bean定义类型
-->
    <bean id="bookDao" class="com.bh.dao.Impl.BookDaoImpl"/>
</beans>

之后在外部类上使用这个类的save方法,如下:

package com.bh;

import com.bh.dao.BookDao;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class Test2 {

    public static void main(String[] args) {

        ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");

        BookDao bookDao = (BookDao) ctx.getBean("bookDao");

        bookDao.save();

        }
}

运行结果:
请添加图片描述
假设这个BookDao是一个数据库的相关操作类,这里还有一个业务类BookService,用来调用BookDao下的save方法,实现如下:
BookService

package com.bh.service;

public interface BookService {

    void save();
}

BookService实现类BookServiceImpl

package com.bh.service.Impl;

import com.bh.dao.BookDao;
import com.bh.service.BookService;

public class BookServiceImpl implements BookService {

    private BookDao bookDao;

    public void setBookDao(BookDao bookDao) {
        this.bookDao = bookDao;
    }

    public void save() {
        bookDao.save();
    }
}

在applicationContext.xml配置文件为:
applicationContext.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"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">



<!--
bean 标签表示配置bean
id属性表示给bean起名字
class属性表示给bean定义类型
-->
    <bean id="bookDao" class="com.bh.dao.Impl.BookDaoImpl"/>

    <bean id="bookService" class="com.bh.service.Impl.BookServiceImpl">
<!--        property 标签表示配置当前bean的属性
            name 属性表示配置哪一个具体的属性
            ref 属性表示参照哪一个bean
-->
        <property name="bookDao" ref="bookDao"/>
    </bean>


</beans>

【注】:在BookServiceImpl类中一定要写对应的setter方法,applicationContext.xml配置文件中property标签的name就是在BookServiceImpl私有属性bookDao,ref就是参照哪一个bean。
测试如下

package com.bh;

import com.bh.service.BookService;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class Test2 {

    public static void main(String[] args) {

        ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");

        BookService bookservice = (BookService) ctx.getBean("bookService");

        bookservice.save();

        }
}

运行结果和上述相同,本质上就是调用相同的方法。

2. 静态工厂

其实就是实现一个工厂类,下有一个静态方法,用于返回某一个实例化对象,如下:
BookFactory

package com.bh.factory;

import com.bh.dao.BookDao;
import com.bh.dao.Impl.BookDaoImpl;

public class BookFactory {
    public static BookDao getBookDao(){
        return new BookDaoImpl();
    }
}

配置文件applicationContext.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"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">

    <bean id="bookDao2" class="com.bh.factory.BookFactory" factory-method="getBookDao"/>
</beans>

测试代码

package com.bh;

import com.bh.dao.BookDao;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class Test2 {
    public static void main(String[] args) {
        ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
        BookDao bookDao2 = (BookDao) ctx.getBean("bookDao2");
        bookDao2.save();
    }
}

运行结果同上。

3. 实例工厂

和第2点一样,只不过不是用静态方法返回一个实例化对象,而是一个普通方法,如下:
BookFactory2

package com.bh.factory;

import com.bh.dao.BookDao;
import com.bh.dao.Impl.BookDaoImpl;

public class BookFactory2 {

    public BookDao getBookDao(){
        return new BookDaoImpl();
    }
}

配置文件applicationContext.mxl

<?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">

<!--    实例化工厂-->
    <bean id="bookFactory2" class="com.bh.factory.BookFactory2"/>
    <bean id="bookDao3" factory-method="getBookDao" factory-bean="bookFactory2"/>
</beans>

测试代码

package com.bh;

import com.bh.dao.BookDao;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class Test2 {
    public static void main(String[] args) {
        ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
        BookDao bookDao3 = (BookDao) ctx.getBean("bookDao3");
        bookDao3.save();
    }
}

运行结果同上。
这种方式在配置文件中创建了两个bean,前一个是为后一个bean服务的,这样显得这个bean除了这个服务之外,毫无用处,于是可以对第三种方式进行改进,如下:
新建BookFactory3,让其实现接口FactoryBean,并实现其对应的方法getObject和getObjectType,如下:
BookFactory3

package com.bh.factory;

import com.bh.dao.BookDao;
import com.bh.dao.Impl.BookDaoImpl;
import org.springframework.beans.factory.FactoryBean;

public class BookFactory3 implements FactoryBean<BookDao> {
    public BookDao getObject() throws Exception {
        return new BookDaoImpl();
    }

    public Class<?> getObjectType() {
        return BookDao.class;
    }
}

applicationContext.xml中只需一个bean即可,如下:

<?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">

    <bean id="bookDao3" class="com.bh.factory.BookFactory3"/>
</beans>

在运行上述测试代码,运行结果依旧,这种方式创建的BookDao是单例的,FactoryBean接口里还有一个实现了的方法的isSingleton,默认返回true,把这个方法进行重写,返回false,就不是单例的了。请添加图片描述

风语者!平时喜欢研究各种技术,目前在从事后端开发工作,热爱生活、热爱工作。