[Java]Spring-Day 1

[Java]Spring-Day1

学习使用工具

黑马2023新版Java视频教程 https://www.bilibili.com/video/BV1Fv4y1q7ZH?p=8&vd_source=03da0cdb826d78c565cd22a83928f4c2

Java程序员进阶之路 https://tobebetterjavaer.com/overview/java-can-do-what.html

黑马程序员SSM框架教程 https://www.bilibili.com/video/BV1Fi4y1S7ix?p=2&vd_source=03da0cdb826d78c565cd22a83928f4c2

JAVA三层架构 https://cloud.tencent.com/developer/article/1933722

JAVA静态工厂 https://developer.aliyun.com/article/862351

一、Spring Framework 4系列系统架构

  • Core Container:核心容器,里面装了各种对象
    • Beans
    • Core
    • Context
    • SpEL
  • AOP:面向切面编程 & Aspects:AOP思想实现
  • Data Access/Integration:数据访问/数据集成
    • JDBC
    • ORM
    • OXM
    • JMS
    • Transactions:事务
  • Web:Web开发
  • Test:单元测试与集成测试

JAVA的三层架构: 1、表示层(UI), 2、业务逻辑层(BLL), 3、数据访问层(DAL),又称持久层。

表示层:为用户提供交互操作界面。

业务逻辑层:负责关键业务的处理和数据的传递。复杂的逻辑判断和涉及到数据库的数据验证都需要在此做出处理。根据传入的值返回用户想得到的值,或者处理相关的逻辑。

数据访问层:负责数据库数据的访问。主要为业务逻辑层提供数据,根据传入的值来操作数据库,增、删、改、查。

二、Core Container

  • IoC(控制反转)思想:对象的创建控制权由程序转移到外部。为了解决Java代码耦合度偏高的问题,提出解决方案:使用对象时,在程序中不要主动使用new产生对象,转换为由外部提供对象。
    • Spring提供了一个容器,称为IoC容器(即Core Container),用来充当IoC思想中的“外部”。IoC容器负责对象的创建、初始化等一系列工作,被创建或被管理的对象在IoC容器中统称为Bean
  • DI(依赖注入):在容器中建立bean与bean之间的依赖关系的整个过程,称为依赖注入。
  • 最终效果:解耦。使用对象时不仅可以直接从IoC容器中获取,并且获取到的bean已经绑定了所有的依赖关系。

三、IoC入门案例

  1. 思路分析
    • 管理什么?-对象
    • 如何将被管理的对象告知IoC容器?-配置文件
    • 被管理的对象交给IoC容器,如何获取到IoC容器?-接口
    • IoC容器得到后,如何从容器中获取bean?-接口方法
  2. 案例实现
    • 配置文件写法:配置文件命名为applicationContext.xml,内容为<bean id = "" class = ""/>,id属性表示给bean命名,class属性标识给bean定义类型,即class的坐标。id属性在同一个上下文中不能重复

    • 代码

      ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml") // 获取IoC容器
         
      BookDao bookDao = (ClassType)ctx.getBean("") // 获取bean,引号内填bean的id
      

四、DI入门案例

  1. 思路分析

    • 基于IoC管理bean
    • 类A中使用new形式创建的对象B是否保留?-否
    • 类A中需要的对象B如何进入到类A中?-提供方法
    • 类A与对象B间的关系如何描述?-配置
  2. 案例实现

    • 提供方法:通过set方法

    • 配置文件关系写法:

      <bean id = "bookDao" class = ""/>
      <bean id = "bookService" class = "">
      	<property name = "bookDao" ref = "bookDao"/>
      </bean>
      

      property标签表示配置当前bean的属性,name属性标识配置哪一个具体的属性,ref属性标识参照哪一个bean

五、bean详解

  1. 配置

    <bean id = "bookDao" name = "" class = "" scope = ""/>

    name中可以增加别名,可以添加多个,以逗号、分号、空格分割。scope中可以定义bean作用范围,singleton为单例(默认),prototype为非单例

    • 单例对象:是一种特殊的类,有且只有一个实例
    • 适合交给容器进行管理的bean:表现层对象、业务层对象、数据层对象、工具对象(可以复用的)
    • 不适合交给容器进行管理的bean:封装实体的域对象
  2. 使用构造方法实例化

    bean本质上就是对象,创建bean使用构造方法完成。一般来说,bean调用的是无参构造方法,如果没有提供无参构造方法,将抛出异常BeanCreationException

  3. 使用静态工厂实例化

    在 Java 中,获得一个类实例最简单的方法就是使用 new 关键字,通过构造函数来实现对象的创建。

        Fragment fragment = new MyFragment();
        Date date = new Date();
    

    不过在实际的开发中,我们经常还会见到另外一种获取类实例的方法:

        Fragment fragment = MyFragment.newIntance();
        Calendar calendar = Calendar.getInstance();
        Integer number = Integer.valueOf("3");
    

    像这样的不通过 new,而是用一个静态方法来对外提供自身实例的方法,即为我们所说的静态工厂方法(Static factory method)

    public static Person getNewPerson(String name, int age, String skill) {
    
        if (StringUtils.isBlank(skill)){
            return new Person(name, age);
        }
    
        return  new Person(name, age, skill);
    }
    

    以上是使用静态工厂方法来返回一个Person的实例对象,我们可以先不管方法体内的判断逻辑,只看返回值为一个Person对象。该静态工厂方法的功能和构造器类似,可以直接调用方法返回与构造器相同的结果。

    优点:

    • 实际在开发过程中,我们可能会根据业务定义多个构造函数。这时候可以直接通过静态工厂方法的名字区分,这样就更清晰明确。
    • 可以通过写静态工厂方法来统一返回一个对象,也就是不必每次调用静态工厂方法的时候每次都创建一个新的对象。
    • 通过该静态方法可以返回任何子类型的对象,且对调用者可以直接屏蔽实例化对象的类型。
    • 静态工厂方法返回对象的类,可以是在定义静态工厂方法的时候不存在的。

    在spring中,使用静态工厂实例化bean的方法如下:

    <bean id = "bookDao" class = "" factory-method = ""/>,class内填写静态工厂类,factory-method指定工厂内的方法。

  4. 使用实例工厂实例化

    实例工厂与静态工厂基本相同,但静态工厂以static修饰,实例工厂不用static修饰。

    在spring中,使用实例工厂实例化bean的方法如下:

    <bean id = "bookFactory" class = ""/>
    <bean id = "bookDao" factory-method = "" factory-bean = "bookFactory"/>
    

    先配置实例工厂bean,再配置需要的bean。

  5. 实例工厂的改良:FactoryBean

    实例工厂的编写:

    public class UserDaoFactoryBean implements FactoryBean<UserDao>{
        //代替原始实例工厂中创建对象的方法
        public UserDao getObject() throws Exception{
            return new UserDaoImp1();
        }
        public Class<?> getObjectType(){
            return UserDao.class;
        }
        public boolean isSingleton(){
            return true; //当false的时候就是非单例的
        }
    }
    

    bean的配置:

    <bean id = "userDao" class="UserDaoFactoryBean">

  6. bean的生命周期

    • 初始化容器:
      • 创建对象(内存分配)
      • 执行构造方法
      • 执行属性注入(Set操作)
      • 执行bean初始化方法
    • 使用bean
    • 关闭/销毁容器:执行bean销毁方法
    public class BookDaoImp1 implements BookDao{
        public void init(){
            // 表示bean初始化对应的操作
        }
        public void destroy(){
            // 表示bean销毁时对应的操作
        }
    }
    

    配置:

    <bean id = "bookFactory" class = "" init-method = "init" destory-method = "destroy"/>

    或者在编写类时就加上接口:

    public class BookDaoImp1 implements BookDao, InitializingBean, DisposableBean{
        public void afterPropertiesSet() throws Exception{
            // 表示bean初始化对应的操作
        }
        public void destroy() throws Exception{
            // 表示bean销毁时对应的操作
        }
    }
    

    配置时就不需要再指定init-methoddestory-method了。

六、依赖注入

  • setter注入

    • 简单类型

      <bean id = "bookService" class = "">
      	<property name = "" value = ""/>
      </bean>
      

      name指定需要注入的变量名,value指定值。指定值时需要带双引号,与类型本身的值无关,java自己会进行类型转换。

    • 引用类型:参考DI入门案例中使用ref进行配置。

  • 构造器注入:不使用set方法,而在构造方法中进行注入(即有参构造方法)

    • 简单类型

      <bean id = "bookService" class = "">
      	<constructor-arg name = "" value = ""/>
      </bean>
      

      也可以用类型进行指定:

      <bean id = "bookService" class = "">
      	<constructor-arg type = "int" value = ""/>
          <constructor-arg type = "java.lang.String" value = ""/>
      </bean>
      

      也可以用顺序进行指定:

      <bean id = "bookService" class = "">
      	<constructor-arg index = "0" value = ""/>
          <constructor-arg index = "1" value = ""/>
      </bean>
      
    • 引用类型

      <bean id = "bookService" class = "">
      	<constructor-arg name = "" ref = ""/>
      </bean>
      

    依赖注入方式选择:强制依赖使用构造器进行,使用setter注入有概率不进行注入导致null对象出现;可选依赖使用setter注入进行,灵活性强。Spring框架倡导使用构造器,自己开发的模块推荐使用setter注入。

七、依赖自动装配

IoC容器根据bean所依赖的资源在容器中自动查找并注入到bean中的过程称为自动装配,用于对引用类型依赖注入,不能对简单类型进行操作。

自动装配优先级低于setter注入与构造器注入。

自动装配方式:

  • 按类型(常用):需要提供set方法。此时必须要保障容器中相同类型的Bean唯一。

    <bean id = "bookService" class = "" autowire = "byType"/>
    
  • 按名称:需要提供set方法。此时必须要保障容器中具有指定名称的bean。

    <bean id = "bookService" class = "" autowire = "byName"/>
    
  • 按构造方法(不常用)

八、集合注入

  • 数组

    <bean id = "bookService" class = "">
    	<property name = "array">
            <array>
                <value>100</value>
                <value>200</value>
            </array>
        </property>
    </bean>
    
  • List

    <bean id = "bookService" class = "">
    	<property name = "list">
            <list>
                <value>one</value>
                <value>two</value>
            </list>
        </property>
    </bean>
    
  • Set

    <bean id = "bookService" class = "">
    	<property name = "set">
            <set>
                <value>one</value>
                <value>two</value>
            </set>
        </property>
    </bean>
    
  • Map

    <bean id = "bookService" class = "">
    	<property name = "map">
            <map>
                <entry key = "country" value = "china">
                <entry key = "city" value = "anqing">
            </map>
        </property>
    </bean>
    
  • Properties

    <bean id = "bookService" class = "">
    	<property name = "propties">
            <props>
                <prop key = "country">china</prop>
                <prop key = "city">anqing</prop>
            </props>
        </property>
    </bean>
    

posted @ 2023-03-26 20:07  无机呱子  阅读(25)  评论(0编辑  收藏  举报