栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

Spring day(2)

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Spring day(2)

Spring Bean

一、Bean的配置二、Bean的实例化

2.1 构造方法实例化2.2 静态工厂实例化2.3 实例工厂实例化 三、Bean的作用域

3.1 singleton 作用域3.2 prototype 作用域 四、Bean的生命周期五、Bean的装配方式

5.1 基于XML配置的装配5.2 基于注解的装配


spring学习记录
在Spring应用中,Spring IOC容器可以创建、装配和配置应用组件对象,这里的组件对象称为Bean。 一、Bean的配置

    Spring可以看作一个大型工厂,用于生产和管理Spring容器中的Bean。如果要使用这个工厂生产和管理Bean,需要开发者将Bean配置在Spring的配置文件(支持XML和Properties)中。

    XML配置文件的根元素是 , 中包含了多个子元素,每个元素定义一个Bean,并描述Bean如何被配置到Spring容器中。

    元素的常用属性及其子元素如下:

属性或子元素名称描述
idBean在BeanFactory中的唯一标识,在代码中通过BeanFactory获取Bean实例时需要作为索引名称
classBean的具体实现类,使用类的名
scop指定Bean实例的作用域
元素的子元素,使用构造方法注入,指定构造方法的参数。该元素index属性指定参数的序号,ref属性指定对BeanFactory中的其他Bean的引用关系,type属性指定参数类型,value属性指定参数的常量值
元素的子元素,用于设置一个属性。该元素的name属性指定Bean实例中相应的属性名称,value属性指定Bean属性值,ref属性指定属性对BeanFactory中其他Bean的引用关系
元素的子元素,用于封装List或数组类型的依赖注入
元素的子元素,用于封装Map类型的依赖注入
元素的子元素,用于封装Set类型的依赖注入
元素的子元素,用于设置一个键值对。

Bean的配置示例代码:

  
    
    
    
        
    
二、Bean的实例化

在Spring框架中,如果想使用Spring容器中的Bean,需要实例化Bean。Spring框架示例化Bean有3中方式,构造方法实例化(常用)、静态工厂实例化和示例实例实例化。

2.1 构造方法实例化

在Spring框架中,Spring容器可以调用Bean对应类中的无参构造方法来实例化Bean,这种方式称为构造方法实例化。

    准备一个spring项目或者web项目导入spring jar包

需要的基本jar包:

commons-logging-1.2.jarspring-beans-5.2.3.RELEASE.jarspring-context-5.2.3.RELEASE.jarspring-core-5.2.3.RELEASE.jarspring-expression-5.2.3.RELEASE.jar

    src目录下新建一个instance包,并创建BeanClass类

定义一个message字符串测试无参构造方法实例化Bean。

public class BeanClass {
    public String message;
    public BeanClass(){
        message = "构造方法实例化Bean";
    }
    
    public BeanClass(String s){
        message = s;
    }

    src目录下的创建applicationContext.xml配置文件

定义一个id为constructorInstance的Bean

    
    测试类测试构造方法实例化
public class SpringTest {
    public static void main(String[] args) {
        //初始化Spring容器的ApplicationContext,加载配置文件
        ApplicationContext applicationContext =new ClassPathXmlApplicationContext("applicationContext.xml");
        //测试构造方法实例化Bean
        BeanClass beanClass = (BeanClass) applicationContext.getBean("constructorInstance");
        System.out.println(beanClass + beanClass.message);
    }
}
    测试结果

2.2 静态工厂实例化

使用静态工厂实例化时要求在工厂类中创建一个静态方法来创建Bean的实例。

    在instance包中创建工厂类BeanStaticFactory

使用静态方法createInstance()实例化对象。

public class BeanStaticFactory {
    private static BeanClass beanInstance = new BeanClass("调用静态工厂方法实例化Bean");
    public static BeanClass createInstance(){
        return beanInstance;
    }
}

    在applicationContext.xml文件中配置Bean
    class属性指定静态工厂类,factory-method属性指定工厂类中的静态方法
    
    测试类中进行测试
public class SpringTest {
    public static void main(String[] args) {
        //初始化Spring容器的ApplicationContext,加载配置文件
        ApplicationContext applicationContext =new ClassPathXmlApplicationContext("applicationContext.xml");
        //测试构造方法实例化Bean
        BeanClass beanClass = (BeanClass) applicationContext.getBean("constructorInstance");
        System.out.println(beanClass + beanClass.message);

        //测试静态工厂实例化Bean
        BeanClass beanClass2 = (BeanClass) applicationContext.getBean("staticFactoryInstance");
        System.out.println(beanClass2 + beanClass2.message);
    }
}
    测试结果

2.3 实例工厂实例化

实例工厂实例化Bean时要求开发者在工厂类中建立一个实例方法来出啊那赶紧Bean的实例

    创建工厂类BeanInstanceFactory
    创建实例方法createBeanClassInstance实例化BeanClass对象
public class BeanInstanceFactory {
    public BeanClass createBeanClassInstance() {
        return new BeanClass("调用实例工厂方法实例化Bean");
    }
}
    在applicationContext.xml文件中配置Bean
    配置Bean时需要使用factory-bean属性指定配置工厂,使用factory-method属性指定使用工厂中的那个方法实例化Bean
    
    
    
     
    测试类进行测试
public class SpringTest {
    public static void main(String[] args) {
        //初始化Spring容器的ApplicationContext,加载配置文件
        ApplicationContext applicationContext =new ClassPathXmlApplicationContext("applicationContext.xml");
        //测试构造方法实例化Bean
        BeanClass beanClass = (BeanClass) applicationContext.getBean("constructorInstance");
        System.out.println(beanClass + beanClass.message);

        //测试静态工厂实例化Bean
        BeanClass beanClass2 = (BeanClass) applicationContext.getBean("staticFactoryInstance");
        System.out.println(beanClass2 + beanClass2.message);

        //测试实例化工厂实例化Bean
        BeanClass beanClass3 = (BeanClass) applicationContext.getBean("instanceFactoryInstance");
        System.out.println(beanClass3 + beanClass3.message);
	}
}
    测试结果

以上为Bean实例化的三种方法。

三、Bean的作用域
作用域名称描述
singleton默认的作用域,使用singleton定义的Bean在Spring容器中只有一个Bean实例
prototypeSpring容器每次获取prototype定义的Bean,容器都将创建一个新的Bean实例
request在一次HTTP请求中容器将返回一个Bean实例,不同的HTTP请求返回不同的Bean实例。仅在Web Spring 应用程序上下文中使用
session在一个HTTP Session中,容器将返回同一个Bean实例。仅在Web Spring 应用程序上下文中使用
application为每个ServeltContext对象创建一个实例,即同一个应用共享一个Bean实例。仅在Web Spring 应用程序上下文中使用
websocket为每个WebSockert对象创建一个Bean实例。仅在Web Spring 应用程序上下文中使用

其中singeton 和 prototype是最常用两种,其他作用域仅在仅在Web Spring 应用程序上下文中使用。

3.1 singleton 作用域

当bean的scope设置为singleton时,SpringIoC容器仅生成盒管理一个Bean实例。在使用id或者name获取Bean实例时,IoC容器将返回共享的Bean实例

    例如之前的构造方法实例化Bean配置文件,
    
或者是


    
    测试类测试
public class SpringTest {
    public static void main(String[] args) {
        //初始化Spring容器的ApplicationContext,加载配置文件
        ApplicationContext applicationContext =new ClassPathXmlApplicationContext("applicationContext.xml");

        //测试构造方法实例化Bean
        BeanClass beanClass1 = (BeanClass) applicationContext.getBean("constructorInstance");
        System.out.println(beanClass1);

        BeanClass beanClass2 = (BeanClass) applicationContext.getBean("constructorInstance");
        System.out.println(beanClass2);

    结果

可以看出返回的Bean实例只有一个。

3.2 prototype 作用域
    同理,配置文件将scope设置为"prototype"
    
    
    测试类测试测试结果


可以看出,两次获取Bean实例时,IoC容器返回两个不同的Bean实例。

四、Bean的生命周期

一个对象的生命周期包括创建(实例化与初始化)、使用以及销毁等阶段,Spring中,Bean对象周期也遵循这一过程,但是Spring提供了许多对外接口,允许开发者对三个过程(实例化、初始化、销毁)的前后做一些操作。在Spring Bean中,实例化时为Bean对象开辟空间,初始化则是对属性的初始化。

Spring容器可以管理singleton作用域Bean的生命周期,在此作用域下,Spring能够精确知道Bean何时被创建,何时初始化完成,以及何时被销毁。对于prototype作用域的Bean,Spring只负责创建,当容器创建了Bean实例后,Bean实例就交给了客户端的代码管理器,Spring容器将不再跟踪其生命周期,并且不会管理那些被配置成prototype作用域的Bean。

Bean生命周期:

    根据Bean的配置情况实例化一个Bean根据Sprig上下文对实例化的Bean进行依赖注入,即对Bean的属性进行初始化如果Bean实现了BeanNameAware接口,将调用它实现的setBeanName(String BeanId)方法,此处参数传的是Sping配置文件Bean的id。如果Bean实现了BeanFactoryAware接口,将调用它实现的SetBeanFactory方法,此处参数传递的是当前Spring工厂实例的引用。如果Bean实现了ApplicationContextAware接口,将调用它实现的SetApplicationContext(ApplicationContext)方法,此处参数传递的是Spring上下文实例的引用。如果Bean关联了BeanPostProcessor接口,将调用初始化方法postProcessBeforeInitialization(Object obj,String s)对Bean操作。如果Bean实现了InitializingBean接口,将调用afterPropertiesSet方法。如果Bean在Spring配置文件中配置了init-method属性,将自动调用其配置的初始化方法。如果Bean关联了BeanPostProcessor接口,将调用初始化方法postProcessAfterInitialization(Object obj,String s)方法,由于在Bean初始化结束时调用After方法,也可用于内存缓存技术。

以上完成了就可以使用该Bean,Bean的作用域是singleton,所以调用的是同一个Bean。
    当Bean不在需要时进入销毁阶段,如果Bena实现了DisposableBean接口,则调用其实现的destroy方法将Spring中的Bean销毁。如果在配置文件中通过destroy-method属性制定了Bean的销毁方法,将调用其配置的销毁方法进行销毁。

Bean生命周期演示:

    创建Bean的实现类

在src目录下创建life包,并创建BeanLife类,在BeanLife创建initMyself和destroyMyself方法,演示初始化和销毁过程。

public class BeanLife {
    public void initMyself() {
        System.out.println(this.getClass().getName() + "执行自定义的初始化方法");
    }

    public void destroyMyself() {
        System.out.println(this.getClass().getName() + "执行自定义的销毁方法");
    }
}
    配置Bean

在Spring配置文件中使用实现类BeanLife配置一个id为beanLife的Bean

    
    测试生命周期

在测试类中进行测试

public class SpringTest {
    public static void main(String[] args) {
        //初始化Spring容器的ClassPathXmlApplicationContext,加载配置文件
        ClassPathXmlApplicationContext classPathXmlApplicationContext =new ClassPathXmlApplicationContext("applicationContext.xml");

        System.out.println("获取对象前");
        BeanLife beanLife = (BeanLife) classPathXmlApplicationContext.getBean("beanLif");
        System.out.println("获取对象后" + beanLife);
        classPathXmlApplicationContext.close();
	}
}

    运行结果

可以看出,加载配置文件时执行了Bean的初始化方法initMyself,在获得对象后,关闭容器时,执行了Bean的销毁方法destroyMyself。

五、Bean的装配方式

Bean的装配方式可以理解为将Bean依赖注入到Spring容器中,Bean的装配方式即Bean依赖注入的方式。

主要有:

基于xml配置的装配基于注解的装配自动装配 5.1 基于XML配置的装配

基于XML的依赖注入有两种方式

构造方法注入

setter方法注入

代码实例:

在src目录下创建assemble包,并新建ComplexUser类,演示构造方法注入和属性的setter方法注入

public class ComplexUser {
    //不同数据类型的依赖注入

    private String name;
    private List hobbyList;
    private Map residenceMap;
    private Set aliasSet;
    private String[] array;

    

    public ComplexUser(String name,List hobbyList,Map residenceMap,Set aliasSet,String[] array){
        super();
        this.name = name;
        this.hobbyList = hobbyList;
        this.residenceMap = residenceMap;
        this.aliasSet = aliasSet;
        this.array = array;
    }

    public ComplexUser(){
        super();
    }

    

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

    public void setHobbyList(List hobbyList) {
        this.hobbyList = hobbyList;
    }

    public void setResidenceMap(Map residenceMap) {
        this.residenceMap = residenceMap;
    }

    public void setAliasSet(Set aliasSet) {
        this.aliasSet = aliasSet;
    }

    public void setArray(String[] array) {
        this.array = array;
    }


    @Override
    public String toString() {
        return "name=" + name + ";hobbyList=" + hobbyList + ";residenceMap=" +residenceMap +"; aliasSet="+ aliasSet +  ";array=" + Arrays.toString(array);
    }
}
    配置文件中配置Bean

构造方法注入的配置:

 
    
        
        
            
                sing
                dance
                running
            
        
        
            
                
                
                
            
        
        
            
                user001
                user002
                user003
            
        
        
            
               aaa
               bbb
            
        
    

属性的setter方法注入的配置:

    
        
        
            
                study
                read
            
        
        
            
                
                
            
        
        
            
                user001
                user002
                user003
            
        
        
            
                ccc
                ddd
            
        
    

    测试类中测试
public class SpringTest {
    public static void main(String[] args) {
        //初始化Spring容器的ApplicationContext,加载配置文件
        ApplicationContext applicationContext =new ClassPathXmlApplicationContext("applicationContext.xml");

       //构造方法装配
        ComplexUser user1 = (ComplexUser) applicationContext.getBean("user1");
        System.out.println(user1);

        //setter方法装配
        ComplexUser user2 = (ComplexUser) applicationContext.getBean("user2");
        System.out.println(user2);
    }
}
    测试结果

以上为构造函数和setter方法注入的装配方式结果。

5.2 基于注解的装配

xml配置文件可以简单的装配Bean,但在大量的Bean需要装配的时候,会导致xml文件过于庞大,且不方便升级与维护,更多的使用注解(annotation)的当时装配Bean。

注解类型

注解作用
@Component该注解是一个泛化的概念,仅仅表示一个组件对象(Bean),可以作用在任何层次上。
@Repository该注解用于将数据访问层(Dao)的类标识为Bean,即注解数据访问层Bean,功能与@Component相同,作用于类前面
@Service该注解用于标注一个业务逻辑组件类(Service),功能与@Component相同,作用于类前面
@Controller该注解用于标注一个控制器组件类(Spring MVC 的Controller),功能与@Component相同,作用于类前面
@Autowired该注解可以对类的成员变量、方法及构造方法进行标注,完成自动装配的工作。通过使用@Autowired来消除setter和getter方法。默认按照Bean的类型进行装配。
@Resource与@Autowired功能一样,区别在于该注解默认是按名称来装配注入的。即@Resource注解有两个属性–name和type。name属性指定Bena实例名称,即安装名称来装配注入;type属性指定Bean类型,即按照Bean的类型进行装配。
@Qualifier该注解与@Autowired注解配合使用。当@Autowired注解需要安装名称来装配注入时需要和该注解一起使用,Bean的实例名称由@Qualifier注解的参数指定
@Scope指定Bena的作用域 ,例如@Scope(scopeName = “singleton”)

代码实例:

    新建annotation包进行演练

创建Dao层,新建TestDao接口和实现类并使用@Repository注解标注为数据访问层

public interface TestDao {
    
    public void save();
}
@Repository("testDao")


public class TestDaoImpl implements TestDao {
    @Override
    public void save() {
        System.out.println("testDao save");
    }
}
    新建service包,并创建testService接口和实现类
public interface TestService {
    
    public void save();
}
@Service


public class TestServiceImpl implements TestService {
    @Resource(name = "testDao")
    

    private TestDao testDao;

    @Override
    public void save() {
        testDao.save();
        System.out.println("testService save");
    }
}
    新建控制器controller层,并使用@Controller注解进行标识,并自动装配逻辑层的Bean。
//不指定Bean的名字,Spring默认给Bean取id名,取名方式为类名第一个字母小写即testController
@Controller
public class TestDao {

    @Autowired
    

    private TestService testService;

    public void save(){
        testService.save();
        System.out.println("testController save");
    }
}

为什么不指定Bean的名字,spring取类名首字母小写的作为Bean名字,大佬的源代码分析spring是如何给bean起名字的

    配置文件进行Bean配置

标签中添加context相关命名空间配置规则标签

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

配置扫描注解

    
    测试类中进行测试
public class SpringTest {
    public static void main(String[] args) {
        //初始化Spring容器的ApplicationContext,加载配置文件
        ApplicationContext applicationContext =new ClassPathXmlApplicationContext("applicationContext.xml");

        TestController testController = (TestController) applicationContext.getBean("testController");
        testController.save();
	}
}

    测试结果

至此Bean的基础就复习就结束了。

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/709316.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号