Spring 基础篇(学习笔记)

案例引入

public class Users {
    public void add(){
        System.out.println("add方法");
    }
}

// ============================================================================

public class Test {
    public static void main(String[] args) {
        // ClassPathXmlApplicationContext 读取的地址是 src 目录下的
        // FileSystemXmlApplicationContext 读取的是带 盘符的地址
        ApplicationContext context = new ClassPathXmlApplicationContext("com/guigu/beans.xml");

        Users user = context.getBean("user", Users.class);

        System.out.println(user);
        user.add();
    }
}

// ============================================================================

<?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="user" class="com.guigu.Users"></bean>
</beans>

IOC 接口

spring 提供 IOC容器 实现两种方式:(两个接口)

BeanFactoryIOC容器基本实现,是spring内部的使用接口,不提供开发人员进行操作;加载配置文件时候不会去创建对象,在获取(使用)对象时才去创建。

ApplicationContext它是BeanFactory的子接口,提供了更多更强大的功能,一般由开发人员使用;加载配置文件时,会把配置文件中的对象进行创建

ApplicationContext的实现类主要是:

  • ClassPathXmlApplicationContext 读取配置文件时,是从 src 目录下读取的
  • FileSystemXmlApplicationContext读取配置文件时,需要从带盘符的地址读取

IOC 具体操作

bean管理

spring 创建对象

spring 注入属性

bean 管理的两种实现方式为:

基于xml配置文件的方式实现

基于注解的方式实现

基于 xml 创建对象

使用bean标签,在里面添加对应的属性,可以创建对象

<bean id="user" class="com.guigu.Users"></bean>

id属性:给对象取得别名

class属性:要创建对象的类的全路径

name属性:与id属性是一样的,可以添加特殊符号(与 strut 配合)

创建对象时,默认执行的是无参的构造方法


基于 xml 注入属性

DI:依赖注入,就是注入属性

  1. 使用set方法注入
// ====Java 类中============================================================================
public class Users {

    private String name;
    private Integer age;

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

    public void setAge(Integer age) {
        this.age = age;
    }
}
// ====xml文件中============================================================================
<bean id="user" class="com.guigu.Users">
    <!-- name中是属性的名称 value里是你要注入的值-->
    <property name="name" value="张三"></property>
    <property name="age" value="22"></property>
</bean>
  1. 使用有参构造注入
// ====Java 类中====================================================================
private String name;
private Integer age;

public Users(String name, Integer age) {
        this.name = name;
        this.age = age;
    }
// ====xml文件中=====================================================================
<bean id="order" class="com.guigu.Users">
    <constructor-arg name="name" value="里斯"></constructor-arg>
    <constructor-arg name="age" value="33"></constructor-arg>
    // 也可以用 index 代替 name 
</bean>

p 名称空间注入

使用p 名称空间注入时,实体类中必须有set方法,其实其本质还是set注入

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

    <bean id="order" class="com.guigu.Users" p:name="王五" p:age="22">
    </bean>
</beans>

IOC操作Bean管理

  1. 字面量
    1. null值 <null/>
    2. 属性包含特殊符号
    3. 把特殊符号进行转义 &lt; &gt
    4. 把特殊符号内容写到CDATA <value> <![CDATA[ <<书名>> ]]> </value>
  1. 注入属性 - 外部 bean

通过server调用dao就叫做引入外部bean

public interface UsersDao {
    public void add();
}
// ====================================================================================
public class UserDaoImpl implements UsersDao {
    @Override
    public void add() {
        System.out.println("UserDaoImpl 的 add 方法");
    }
}
// ====================================================================================
public class UserService {

    private UsersDao usersDao;

    public void setUsersDao(UsersDao usersDao) {
        this.usersDao = usersDao;
    }

    public void add(){
        System.out.println("UserService 的 add 方法");
        usersDao.add();
    }
}
// ====================================================================================
<?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"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">

    <bean id="userService" class="com.guigu.service.UserService">
        <property name="usersDao" ref="UserDaoImpl">
        </property>
    </bean>
    <bean id="UserDaoImpl" class="com.guigu.dao.UserDaoImpl"></bean>
</beans>
  1. 注入属性 - 内部 bean 和 级联赋值
<bean id="userService" class="com.guigu.service.UserService">
  <property name="usersDao">
    <bean id="UserDaoImpl" class="com.guigu.dao.UserDaoImpl">
    </bean>
  </property>
    </bean>

级联赋值就是: 一对多的关系 ==》 部门和员工

<bean id="userService" class="com.guigu.service.UserService">
  <property name="usersDao" ref="UserDaoImpl">
  </property>
</bean>
<bean id="UserDaoImpl" class="com.guigu.dao.UserDaoImpl"></bean>

集合类型的属赋值

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

<bean>
  <!-- 数组类型属性注入-->
  <property name="">
    <array>
      <value>第一元素</value>
      <value>第二元素</value>
    </array>
  </property>
  
  <!-- list 类型属性注入-->
  <property name="">
    <list>
      <value>第一元素</value>
      <value>第二元素</value>
    </list>
  </property>
  
  <!-- map 类型属性注入-->
  <property name="">
    <map>
      <entry key="java" value="java"></entry>
      <entry key="C++" value="C++"></entry>
    </map>
  </property>
  
  <!-- set 类型属性注入-->
  <property name="">
    <set>
      <value>第一元素</value>
      <value>第二元素</value>
      <ref bean="对象的 id 值">加对象</ref>
    </set>
  </property>
</bean>
// ======= 使用 util 标签 ==========================================================
  <util:list id="booklist">
      <value>第一元素</value>
      <value>第二元素</value>
  </util:list>
<bean id="book" class="com.guigu.book">
  <property name="list" ref="booklist">
  </property>
</bean>

IOC 操作 Bean 管理(FactoryBean)

  1. spring中一共有两种类型的bean,一种是普通的bean(就是我们自己创建的),另外一种就是内部的bean也叫工厂bean(FactoryBean)
  2. 普通bean特点:在配置文件中定义的类型,就是返回的类型
  3. 工厂bean的特点:在配置文件中定义bean的类型可以与返回的类型不一样

第一步:创建类,让这个类作为工厂bean,实现接口FactoryBean

第二步:实现接口里面的方法,在实现的方法中定义返回的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="myBean" class="cn.guili.MyBean">
  </bean>
</beans>

// ================================================================================

public class MyBean implements FactoryBean<U_Book> {
  @Override
  public U_Book getObject() throws Exception {
  U_Book u_book = new U_Book("关谷神奇");
  return u_book;
  }
  
  @Override
  public Class<?> getObjectType() {
                        return null;
                    }

                    @Override
                    public boolean isSingleton() {
                        return FactoryBean.super.isSingleton();
                    }
                }

// ================================================================================

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

// ================================================================================

public class TestBean {
    @Test
    public void test(){
        ApplicationContext context = new ClassPathXmlApplicationContext("cn/guili/beans_01.xml");
        U_Book myBean = context.getBean("myBean", U_Book.class);
        System.out.println(myBean);
    }
}

bean的作用域

  1. 在spring里面,设置创建bean实例是单实例还是多实例
  2. 在spring里面,默认情况下,bean是单实例对象
  3. 如何设置是单实例还是多实例
    1. 在bean标签中有个属性 scope 用于设置单实例还是多实例
      1. singleton 默认值,表示是单实例
      2. prototype 表示多实例

<bean id="myBean" class="cn.guili.MyBean" scope="singleton">
</bean>

ApplicationContext context = new ClassPathXmlApplicationContext("cn/guili/beans_01.xml");
U_Book myBean = context.getBean("myBean", U_Book.class);
U_Book myBean1 = context.getBean("myBean", U_Book.class);
System.out.println(myBean);
System.out.println(myBean1);

输出的结果:

cn.guili.U_Book@4fb0f2b9

cn.guili.U_Book@4fb0f2b9

===============================================================

<bean id="myBean" class="cn.guili.MyBean" scope="prototype">
</bean>

ApplicationContext context = new ClassPathXmlApplicationContext("cn/guili/beans_01.xml");
U_Book myBean = context.getBean("myBean", U_Book.class);
U_Book myBean1 = context.getBean("myBean", U_Book.class);
System.out.println(myBean);
System.out.println(myBean1);

输出的结果:

cn.guili.U_Book@5ffead27

cn.guili.U_Book@6356695f

注意:地址不一样证明是一个多实例对象,设置scope值为prototype时候,不是在加载spring配置文件时候创建对象,而是在调用getBean方法时,创建多实例对象

request 一次请求

session 一次对话

bean的生命周期

  1. 生命周期
    1. 从对象的创建到对象的销毁的过程
  1. bean生命周期
    1. 通过构造器创建bean实例(执行无参构造)
    2. 为bean的属性设置值,和对其他bean引用(调用set方法)
    3. 把bean实例传递bean后置处理器的方法 postProcessBeforeInitialization
    4. 调用bean的初始化的方法(需要进行配置初始化方法)
    5. 把bean实例传递bean后置处理器的方法 postProcessAfterInitialization
    6. bean可以使用了(对象获取到了)
    7. 当容器关闭的时候,调用bean的销毁方法(需要进行配置销毁的方法)

代码演示:

class Orders{

private String name;

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

public Orders(){

System.out.println("第一步,执行无参构造创建实例");

}

public void initMethod(){

System.out.println("第三步,执行初始化方法");

}

public void destroyMethod(){

System.out.println("第五步,执行销毁方法");

}

}

<bean id="orders" class="cn.guili.Orders" init-method="initMethod" destroy-method="destroyMethod">
</bean>

ApplicationContext context = new ClassPathXmlApplicationContext("cn/guili/beans_01.xml");
Orders orders= context.getBean("orders", Orders.class);

// 获取对象

System.out.println("第四步,获取bean的实例对象");
System.out.println(orders);

// 销毁的方法

(ClassPathXmlApplicationContext)context.close();

  1. bean的后置处理器,bean 的生命周期一共有七步
// 创建类
public class Mybb implements BeanPostProcessor {
    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        System.out.println("在初始化之前执行");
        return bean;
    }
    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        System.out.println("在初始化之后执行");
        return bean;
    }
}

配置后置处理器

<bean id="myBean" class="cn.guili.Mybb">
</bean>

加载配置文件的时候,会将bean的实例创建,也会把后置处理器创建;当Mybb这个类实现了BeanPostProcessor接口后,spring会将Mybb当成后置处理器去执行,后置处理器会为当前的配置文件中的所有bean都添加一个后置处理器的处理。

(笔记根据尚硅谷哔站视频所记)

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值