Spring入门

    @Test

    public void test01(){

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

        //当程序执行完这条代码,也就是读取完xml配置文件,对象就被创建,而且多次创建的对象为不同个对象

        UserDao userDao1 = (UserDao) app.getBean("userDao");

        UserDao userDao2 = (UserDao) app.getBean("userDao");

        System.out.println(userDao1);

        System.out.println(userDao2);

    }

}



```



![在这里插入图片描述](https://img-blog.csdnimg.cn/70108d2ce2c84e388c1474fa6b8a5776.png#pic_center)



Bean的生命周期:



*   对象创建:当使用对象时,创建新的对象实例

*   对象运行:只要对象在使用中,就一直活着

*   对象销毁:对象长时间不使用,就会被JAVA的垃圾回收器回收了

2、Bean实例化三种方式


Bean实例化的三种方式:

  • 无参构造方法实例化
  • 工厂静态方法实例化
  • 工厂实例方法实例化

2.1、无参构造方法实例化


 <bean id="userDao" class="com.kang.impl.UserDaolmpl"></bean>



上述测试代码中所有的Bean实例化均为无参构造方法


2.2、工厂静态方法实例化


public class UserDaolmplFactory {

    public static UserDaolmpl CreateUserDao(){

        return new UserDaolmpl();

    }

}




<bean id="userDao" class="com.kang.factory.UserDaolmplFactory" factory-method="CreateUserDao"></bean>



只需要在xml文件中,用factory-method告诉spring框架这是一个工厂模式并且工程的方法是CreateUserDao,那么spring框架仍然会返回一个Bean的实例化

spring框架会先找到com.kang.factory.UserDaolmplFactory,然后调用CreateUserDao这个静态方法,即可返回一个UserDao对象

并且java代码不需要有任何修改

在这里插入图片描述


2.3、工厂实例方法实例化

在工厂静态方法实例化的实现中,由于工厂里的方法是静态的,所以不需要创建工厂实例化对象,但是在如果工厂创建对象的方法不是静态的,那应该怎么办?




<bean id="factory" class="com.kang.factory.UserDaolmplFactory"></bean>



<bean id="userDao" factory-bean="factory" factory-method="CreateUserDao"></bean>



  • 首先先创建id为factory的bean,让它返回一个工厂的对象
  • 然后创建一个id为userDao的bean,在当中指明factory-bean(工厂的bean)的id,然后还有工厂创建对象的方法
  • 同样,Java代码不需要修改

在这里插入图片描述


3、Bean生命周期配置


Bean可以由程序猿指定初始化和销毁的方法,只需要在xml配置文件的对应bean中加入以下标签

  • init-method:指定类中的初始化方法名称
  • destroy-method:指定类中的销毁方法名称

<bean id="userDao" class="com.kang.impl.UserDaolmpl" init-method="init" destroy-method="destroy"></bean>




package com.kang.impl;



import com.kang.UserDao;



public class UserDaolmpl implements UserDao {



    public UserDaolmpl(){

        System.out.println("创建对象");

    }



    @Override

    public void save() {

        System.out.println("save running......");

    }



    //初始化方法

    public void init(){

        System.out.println("初始化。。。。");

    }



   //销毁方法

    public void destroy(){

        System.out.println("销毁.....");

    }

}



测试代码


public class SpringTest {

    @Test

    public void test01(){

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

        

        UserDao userDao1 = (UserDao) app.getBean("userDao");

        

        System.out.println(userDao1);

        

        ((ClassPathXmlApplicationContext)app).close();

    }

}



在这里插入图片描述


4、依赖注入


问题引入:

  1. 创建 UserService,UserService 内部在调用 UserDao的save() 方法

public class UserServiceImpl implements UserService {

@Override
public void save() {
    ApplicationContext app = new ClassPathXmlApplicationContext("applicationContext.xml");
    UserDao userDao = (UserDao) app.getBean("userDao");
    userDao.save();
}

}

  1. 将 UserServiceImpl 的创建权交给 Spring
```
<bean id="userDao" class="com.kang.impl.UserDaolmpl"></bean>
    <bean id="userService" class="com.kang.impl.UserServiceImpl"></bean>
```
  1. 从 Spring 容器中获得 UserService 进行操作

@Test

public void test02(){
    ApplicationContext app = new ClassPathXmlApplicationContext("applicationContext.xml");
    UserService userService = (UserService) app.getBean("userService");
    userService.save();
}

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-gT469oAN-1645704192217)(Spring入门.assets/image-20220224093008916.png)]

上述做法是将UserService实例和UserDao都存在spring容器中,然后再容器外部获取UserService实例和UserDao实例,然后在程序中进行结合

在这里插入图片描述

这当中存在的问题是:加载配置文件的时候,不需要getBean方法,配置文件的内容都被执行了,导致配置文件加载了多次,浪费资源

在test中,只需要UserService,但是UserDao也实例化了

因为UserService和UserDao都在Spring容器中,而最终程序直接使用的是UserService,所以可以在 Spring容器中,将UserDao设置到UserService内部。

在这里插入图片描述

要解决这个问题,就需要用到依赖引入

在这里插入图片描述


4.1、依赖引入的方式

通过构造方法和set方法实现将UserDao注入到UserService内部


4.1.1、set方法注入

set方法注入的前提,是要在UserServiceImpl里定义一个私有变量UserDao

然后通过set方法给该私有变量赋值


public class UserServiceImpl implements UserService {

    private UserDao userDao;

    @Override

    public void save() {

        userDao.save();

    }



    public void setUserDao(UserDao userDao) {

        this.userDao = userDao;

    }

}




    <bean id="userDao" class="com.kang.impl.UserDaolmpl"></bean>

    <bean id="userService" class="com.kang.impl.UserServiceImpl">

        <!--第一个userDao是指set方法后面的UserDao, 既setUserDao-->

        <!--第二个userDao 是指上面的id的userDao的Bean实例化返回的UserDao对象-->

        <property name="userDao" ref="userDao"/>

    </bean>



注意:虽然两个userDao写法一样,但是两个userDao所代表的意思并不一样,注意区分

set方法注入还可以用P空间命名注入

首先引入P空间命名空间:

xmlns:p=“http://www.springframework.org/schema/p”

接着,修改注入方式:

    <!--第一个userDao是指set方法后面的UserDao(首字母大写换小写), 既setUserDao-->
    <!--第二个userDao 是指上面的id的userDao(对象引用)-->
    <!--<property name="userDao" ref="userDao"/>-->
</bean>

spring的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"

       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="factory" class="com.kang.factory.UserDaolmplFactory"></bean>-->

    <!--<bean id="userDao" factory-bean="factory" factory-method="CreateUserDao"></bean>-->

    <!--<bean id="userDao" class="com.kang.impl.UserDaolmpl" init-method="init" destroy-method="destroy"></bean>-->



    <bean id="userDao" class="com.kang.impl.UserDaolmpl"></bean>

    <bean id="userService" class="com.kang.impl.UserServiceImpl" p:userDao-ref="userDao">

        <!--第一个userDao是指set方法后面的UserDao, 既setUserDao-->

        <!--第二个userDao 是指上面的id的userDao-->

        <!--<property name="userDao" ref="userDao"/>-->

    </bean>



</beans>




4.1.2、通过构造方法注入

创建有参构造方法


package com.kang.impl;



import com.kang.dao.UserDao;

import com.kang.service.UserService;

import org.springframework.context.ApplicationContext;

import org.springframework.context.support.ClassPathXmlApplicationContext;



/**

 * @ClassName UserServiceImpl

 * @Description TODO

 * @Author kang

 * @Date 2022/2/24 上午 9:22

 * @Version 1.0

 */

public class UserServiceImpl implements UserService {

    private UserDao userDao;



    public UserServiceImpl(UserDao userDao) {

        this.userDao = userDao;

    }



    public UserServiceImpl() {

    }



    @Override

    public void save() {

        userDao.save();

    }



}



配置spring的xml配置文件


<bean id="userDao" class="com.kang.impl.UserDaolmpl"></bean>

    <bean id="userService" class="com.kang.impl.UserServiceImpl" >

        <!--第一个userDao是指有参构造方法的参数-->

        <!--第二个userDao是指引用对象,即上面的id属性-->

        <constructor-arg name="userDao" ref="userDao"></constructor-arg>

</bean>



Java的测试类代码依然不用变

在这里插入图片描述


5、Bean的依赖注入的数据类型


Bean的依赖注入的数据类型有很多种,除了上面的对象还支持普通数据类型,集合等可以在容器中进行注入

注入的三种基本数据类型

  • 普通数据类型
  • 引用数据类型
  • 集合数据类型

上述对对象的操作就是对引用数据类型的依赖注入


5.1、普通数据类型的注入


public class UserServiceImpl implements UserService {

    private String name;

    private int age;



    public void setName(String name) {

        this.name = name;

    }



    public void setAge(int age) {

        this.age = age;

    }



    @Override

    public void save() {

        System.out.println("name = " + name);

        System.out.println("age = " + age);

    }



}




    <bean id="userService" class="com.kang.impl.UserServiceImpl">

        <property name="name" value="小明"></property>

        <property name="age" value="18"></property>

    </bean>



在这里插入图片描述

注意:ref 和 value的使用场景不一样

  • ref:对象引用
  • value:普通数据

5.2、集合数据类型(List< String >)的注入


package com.kang.impl;



import com.kang.dao.UserDao;

import com.kang.service.UserService;

import org.springframework.context.ApplicationContext;

import org.springframework.context.support.ClassPathXmlApplicationContext;



import java.util.List;



public class UserServiceImpl implements UserService {

    List<String> list;



    public void setList(List<String> list) {

        this.list = list;

    }



    @Override

    public void save() {

        System.out.println(list);

    }



}




    <bean id="userService" class="com.kang.impl.UserServiceImpl">

        <property name="list">

            <list>

                <value>华为</value>

                <value>小米</value>

                <value>苹果</value>

            </list>

        </property>

    </bean>



在这里插入图片描述

上述是集合中为普通数据类型的案例


5.3、集合数据类型(List< User >)的注入


package com.kang.poj;



/**

 * @ClassName User

 * @Description TODO

 * @Author kang

 * @Date 2022/2/24 下午 4:29

 * @Version 1.0

 */

public class User {

    private String name;

    private int age;



    public String getName() {

        return name;

    }



    public void setName(String name) {

        this.name = name;

    }



    public int getAge() {

        return age;

    }



    public void setAge(int age) {

        this.age = age;

    }



    @Override

    public String toString() {

        return "User{" +

                "name='" + name + '\'' +

                ", age=" + age +

                '}';

    }

}




package com.kang.impl;



import com.kang.poj.User;

import com.kang.service.UserService;



import java.util.List;



public class UserServiceImpl implements UserService {

    List<User> list;



    public void setList(List<User> list) {

        this.list = list;

    }



    @Override

    public void save() {

        System.out.println(list);

    }



}




    <bean id="user1" class="com.kang.poj.User">

        <property name="name" value="小红"></property>

        <property name="age" value="18"></property>

    </bean>



    <bean id="user2" class="com.kang.poj.User">

        <property name="name" value="小明"></property>

        <property name="age" value="20"></property>

    </bean>



    <bean id="userService" class="com.kang.impl.UserServiceImpl">

        <property name="list">

            <list>

                <ref bean="user1"/>

                <ref bean="user2"/>

            </list>

        </property>

    </bean>



在配置文件中首先先要配置两个bean实例化的对象,然后将他们放到集合中


5.4、集合数据类型(Map< String, User >)的注入

将5.3的List集合改为Map集合,接着spring的XML文件配置修改为以下


    <bean id="userService" class="com.kang.impl.UserServiceImpl">

        <property name="list">

            <map>

                <entry key="第一个人" value-ref="user1"/>

                <entry key="第二个人" value-ref="user2"/>

            </map>

        </property>

    </bean>


### 最后

现在正是金三银四的春招高潮,前阵子小编一直在搭建自己的网站,并整理了全套的**【一线互联网大厂Java核心面试题库+解析】:包括Java基础、异常、集合、并发编程、JVM、Spring全家桶、MyBatis、Redis、数据库、中间件MQ、Dubbo、Linux、Tomcat、ZooKeeper、Netty等等**

![image](https://img-blog.csdnimg.cn/img_convert/46f6410e41aab6176d9085f452fa8a76.webp?x-oss-process=image/format,png)

 class="com.kang.poj.User">

        <property name="name" value="小明"></property>

        <property name="age" value="20"></property>

    </bean>



    <bean id="userService" class="com.kang.impl.UserServiceImpl">

        <property name="list">

            <list>

                <ref bean="user1"/>

                <ref bean="user2"/>

            </list>

        </property>

    </bean>



在配置文件中首先先要配置两个bean实例化的对象,然后将他们放到集合中


5.4、集合数据类型(Map< String, User >)的注入

将5.3的List集合改为Map集合,接着spring的XML文件配置修改为以下


    <bean id="userService" class="com.kang.impl.UserServiceImpl">

        <property name="list">

            <map>

                <entry key="第一个人" value-ref="user1"/>

                <entry key="第二个人" value-ref="user2"/>

            </map>

        </property>

    </bean>


### 最后

现在正是金三银四的春招高潮,前阵子小编一直在搭建自己的网站,并整理了全套的**【一线互联网大厂Java核心面试题库+解析】:包括Java基础、异常、集合、并发编程、JVM、Spring全家桶、MyBatis、Redis、数据库、中间件MQ、Dubbo、Linux、Tomcat、ZooKeeper、Netty等等**

[外链图片转存中...(img-9AHRJQJy-1714471989167)]

> **本文已被[CODING开源项目:【一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码】](https://bbs.csdn.net/topics/618154847)收录**
  • 18
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值