侧边栏壁纸
博主头像
Epoch

Java开发、Python爬虫、微服务、分布式、前端

  • 累计撰写 92 篇文章
  • 累计创建 109 个标签
  • 累计收到 0 条评论

目 录CONTENT

文章目录

Spring-Ioc学习

Epoch
2021-03-07 / 0 评论 / 0 点赞 / 260 阅读 / 6,953 字 / 正在检测是否收录...

1.bean的基本配置

1.创建Maven工程,导入相关依赖

<?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>com.xmaven</groupId>
    <artifactId>Spring_ioc入门-01</artifactId>
    <version>1.0-SNAPSHOT</version>
    
    <properties>
        <maven.compiler.source>8</maven.compiler.source>
        <maven.compiler.target>8</maven.compiler.target>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>5.1.9.RELEASE</version>
        </dependency>
    </dependencies>
</project>

2.创建Service层

package com.xmaven.service;

/**
 * @Author: Ambition
 * @Description TODO
 * @Date: 2021/3/7 12:01 下午
 * @Version 1.0
 */
public interface UserService {

    public void say();

}

3.创建Service的实现层

package com.xmaven.service.impl;

import com.xmaven.service.UserService;

/**
 * @Author: Ambition
 * @Description TODO
 * @Date: 2021/3/7 12:05 下午
 * @Version 1.0
 */
public class UserServiceImpl implements UserService {
    @Override
    public void say() {
        System.out.println("run...");
    }
}

4.注入Spring容器

在Resource目录下面创建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
        https://www.springframework.org/schema/beans/spring-beans.xsd">
    <!--1.创建Spring控制的资源-->
    <bean id="userService" class="com.xmaven.service.impl.UserServiceImpl"></bean>
</beans>

5.编写测试类

package com.xmaven;

import com.xmaven.service.UserService;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

/**
 * @Author: Ambition
 * @Description TODO
 * @Date: 2021/3/7 12:15 下午
 * @Version 1.0
 */
public class UserApp {

    public static void main(String[] args) {
        // 2.加载配置文件
        ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
        // 3.获取资源
        UserService userService = (UserService) ctx.getBean("userService");
        userService.say();
    }
}

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
        https://www.springframework.org/schema/beans/spring-beans.xsd">
    <!--1.创建Spring控制的资源-->
    <bean id="userService" name="service1,service2" class="com.xmaven.service.impl.UserServiceImpl"></bean>
</beans>

获取资源的时候可以用id或者name中的都可以

UserService userService = (UserService) ctx.getBean("service1");
UserService userService = (UserService) ctx.getBean("service2");

2.scope属性

如果在applicationContext.xml中添加

scope=“singleton” 设定创建出的对象保存在Spring容器,开启单例模式 是一个单例对象

scope=“prototype” 设定创建出的对象保存在Spring容器,是一个非单例对象

scope=“其他的如后面写的” request, session,application ,websocket :设定创建的对象放置在web容器对应的位置

<bean id="userService3" scope="singleton" class="com.xmaven.service.impl.UserServiceImpl"></bean>

测试用例

package com.xmaven;

import com.xmaven.service.UserService;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

/**
 * @Author: Ambition
 * @Description TODO
 * @Date: 2021/3/7 12:15 下午
 * @Version 1.0
 */
public class UserApp {

    public static void main(String[] args) {
        // 2.加载配置文件
        ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
        // 3.获取资源
        UserService userService1 = (UserService) ctx.getBean("userService3");
        UserService userService2 = (UserService) ctx.getBean("userService3");
        UserService userService3 = (UserService) ctx.getBean("userService3");
        System.out.println(userService1);
        System.out.println(userService2);
        System.out.println(userService3);
        System.out.println(userService1 == userService2);
//        userService.say();
    }
}

测试其他的socpe自行修改答应对象的地址空间比较

scope用于控制bean创建后的对象是否是单例的

如果判断单例是什么时候创建的,可以加上构造函数和静态代码块检测

修改后如下

package com.xmaven.service.impl;

import com.xmaven.service.UserService;

/**
 * @Author: Ambition
 * @Description TODO
 * @Date: 2021/3/7 12:05 下午
 * @Version 1.0
 */
public class UserServiceImpl implements UserService {

    {
        System.out.println("我是代码块");
    }

    static {
        System.out.println("我是静态代码块");
    }

    public UserServiceImpl() {
        System.out.println("我是无参构造方法");
    }

    @Override
    public void say() {
        System.out.println("run...");
    }
}

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
        https://www.springframework.org/schema/beans/spring-beans.xsd">
    <!--1.创建Spring控制的资源-->
    <!--    <bean id="userService" name="service1,service2" class="com.xmaven.service.impl.UserServiceImpl"></bean>-->

    <bean id="userService3" scope="singleton" class="com.xmaven.service.impl.UserServiceImpl"></bean>
</beans>

防止干扰注释上面的bean对象

测试单例模式的代码

package com.xmaven;

import com.xmaven.service.UserService;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

/**
 * @Author: Ambition
 * @Description TODO
 * @Date: 2021/3/7 12:15 下午
 * @Version 1.0
 */
public class UserApp {

    public static void main(String[] args) {
        // 2.加载配置文件
        ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
        // 3.获取资源
//        UserService userService1 = (UserService) ctx.getBean("userService3");
//        UserService userService2 = (UserService) ctx.getBean("userService3");
//        UserService userService3 = (UserService) ctx.getBean("userService3");
//        System.out.println(userService1);
//        System.out.println(userService2);
//        System.out.println(userService3);
//        System.out.println(userService1 == userService2);
//        userService.say();
    }
}

运行结果

/Library/Java/JavaVirtualMachines/jdk1.8.0_212.jdk/Contents/Home/bin/java -javaagent:/Applications/IntelliJ IDEA.app/Contents/lib/idea_rt.jar=55032:/Applications/IntelliJ IDEA.app/Contents/bin -Dfile.encoding=UTF-8 -classpath /Library/Java/JavaVirtualMachines/jdk1.8.0_212.jdk/Contents/Home/jre/lib/charsets.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_212.jdk/Contents/Home/jre/lib/deploy.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_212.jdk/Contents/Home/jre/lib/ext/cldrdata.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_212.jdk/Contents/Home/jre/lib/ext/dnsns.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_212.jdk/Contents/Home/jre/lib/ext/jaccess.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_212.jdk/Contents/Home/jre/lib/ext/jfxrt.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_212.jdk/Contents/Home/jre/lib/ext/localedata.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_212.jdk/Contents/Home/jre/lib/ext/nashorn.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_212.jdk/Contents/Home/jre/lib/ext/sunec.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_212.jdk/Contents/Home/jre/lib/ext/sunjce_provider.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_212.jdk/Contents/Home/jre/lib/ext/sunpkcs11.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_212.jdk/Contents/Home/jre/lib/ext/zipfs.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_212.jdk/Contents/Home/jre/lib/javaws.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_212.jdk/Contents/Home/jre/lib/jce.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_212.jdk/Contents/Home/jre/lib/jfr.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_212.jdk/Contents/Home/jre/lib/jfxswt.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_212.jdk/Contents/Home/jre/lib/jsse.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_212.jdk/Contents/Home/jre/lib/management-agent.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_212.jdk/Contents/Home/jre/lib/plugin.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_212.jdk/Contents/Home/jre/lib/resources.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_212.jdk/Contents/Home/jre/lib/rt.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_212.jdk/Contents/Home/lib/ant-javafx.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_212.jdk/Contents/Home/lib/dt.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_212.jdk/Contents/Home/lib/javafx-mx.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_212.jdk/Contents/Home/lib/jconsole.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_212.jdk/Contents/Home/lib/packager.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_212.jdk/Contents/Home/lib/sa-jdi.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_212.jdk/Contents/Home/lib/tools.jar:/Users/ambition/IdeaProjects/Spring_ioc入门-01/target/classes:/usr/local/maven/repo/org/springframework/spring-context/5.1.9.RELEASE/spring-context-5.1.9.RELEASE.jar:/usr/local/maven/repo/org/springframework/spring-aop/5.1.9.RELEASE/spring-aop-5.1.9.RELEASE.jar:/usr/local/maven/repo/org/springframework/spring-beans/5.1.9.RELEASE/spring-beans-5.1.9.RELEASE.jar:/usr/local/maven/repo/org/springframework/spring-core/5.1.9.RELEASE/spring-core-5.1.9.RELEASE.jar:/usr/local/maven/repo/org/springframework/spring-jcl/5.1.9.RELEASE/spring-jcl-5.1.9.RELEASE.jar:/usr/local/maven/repo/org/springframework/spring-expression/5.1.9.RELEASE/spring-expression-5.1.9.RELEASE.jar:/usr/local/maven/repo/org/springframework/spring-context/5.1.2.RELEASE/spring-context-5.1.2.RELEASE.jar:/usr/local/maven/repo/org/springframework/spring-aop/5.1.2.RELEASE/spring-aop-5.1.2.RELEASE.jar:/usr/local/maven/repo/org/springframework/spring-beans/5.1.2.RELEASE/spring-beans-5.1.2.RELEASE.jar:/usr/local/maven/repo/org/springframework/spring-core/5.1.2.RELEASE/spring-core-5.1.2.RELEASE.jar:/usr/local/maven/repo/org/springframework/spring-jcl/5.1.2.RELEASE/spring-jcl-5.1.2.RELEASE.jar:/usr/local/maven/repo/org/springframework/spring-expression/5.1.2.RELEASE/spring-expression-5.1.2.RELEASE.jar com.xmaven.UserApp
我是静态代码块
我是代码块
我是无参构造方法

加载文件就new了一个对象

非单例模式呢?

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
        https://www.springframework.org/schema/beans/spring-beans.xsd">
    <!--1.创建Spring控制的资源-->
    <!--    <bean id="userService" name="service1,service2" class="com.xmaven.service.impl.UserServiceImpl"></bean>-->

    <bean id="userService3" scope="prototype" class="com.xmaven.service.impl.UserServiceImpl"></bean>
</beans>

测试发现加载启动文件的时候不创建对象

之后在获取bean对象的时候才加载对象

测试代码如下

package com.xmaven;

import com.xmaven.service.UserService;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

/**
 * @Author: Ambition
 * @Description TODO
 * @Date: 2021/3/7 12:15 下午
 * @Version 1.0
 */
public class UserApp {

    public static void main(String[] args) {
        // 2.加载配置文件
        ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
        // 3.获取资源
        UserService userService1 = (UserService) ctx.getBean("userService3");
//        UserService userService2 = (UserService) ctx.getBean("userService3");
//        UserService userService3 = (UserService) ctx.getBean("userService3");
//        System.out.println(userService1);
//        System.out.println(userService2);
//        System.out.println(userService3);
//        System.out.println(userService1 == userService2);
//        userService.say();
    }
}

3.bean生命周期

名称:init-method , destroy-method
类型:属性
归属:bean标签
作用:定义bean对象在初始化或销毁时完成的工作
格式:
<bean init-method="init" destroy-method="destory"></bean>
取值:bean对应的类中对应的具体方法名

修改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
        https://www.springframework.org/schema/beans/spring-beans.xsd">
    <!--1.创建Spring控制的资源-->
    <!--    <bean id="userService" name="service1,service2" class="com.xmaven.service.impl.UserServiceImpl"></bean>-->

    <!--判断是否是单例模式-->
    <!--<bean id="userService3" scope="singleton" class="com.xmaven.service.impl.UserServiceImpl"></bean>-->

    <bean id="userService3" scope="singleton" init-method="init" destroy-method="destroy" class="com.xmaven.service.impl.UserServiceImpl"></bean>

</beans>

测试代码如下

package com.xmaven;

import com.xmaven.service.UserService;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

/**
 * @Author: Ambition
 * @Description TODO
 * @Date: 2021/3/7 12:15 下午
 * @Version 1.0
 */
public class UserApp {

    public static void main(String[] args) {
        // 2.加载配置文件
        ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
        // 3.获取资源
        UserService userService1 = (UserService) ctx.getBean("userService3");
        UserService userService2 = (UserService) ctx.getBean("userService3");
        UserService userService3 = (UserService) ctx.getBean("userService3");
//        System.out.println(userService1);
//        System.out.println(userService2);
//        System.out.println(userService3);
//        System.out.println(userService1 == userService2);
//        userService.say();
    }
}

输出:

我是静态代码块
我是代码块
我是无参构造方法
容器调用init方法---

可以换成非单例的测试一下

效果不一样

可见这个初始化和销毁和是否是单例是有关的

如果想看到destroy操作可以修改一下类型

测试的代码如下

package com.xmaven;

import com.xmaven.service.UserService;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

/**
 * @Author: Ambition
 * @Description TODO
 * @Date: 2021/3/7 12:15 下午
 * @Version 1.0
 */
public class UserApp {

    public static void main(String[] args) {
        // 2.加载配置文件
//        ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
//        // 3.获取资源
//        UserService userService1 = (UserService) ctx.getBean("userService3");
//        UserService userService2 = (UserService) ctx.getBean("userService3");
//        UserService userService3 = (UserService) ctx.getBean("userService3");
//        System.out.println(userService1);
//        System.out.println(userService2);
//        System.out.println(userService3);
//        System.out.println(userService1 == userService2);
//        userService.say();

        ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
        UserService userService1 = (UserService) ctx.getBean("userService3");
        UserService userService2 = (UserService) ctx.getBean("userService3");
        UserService userService3 = (UserService) ctx.getBean("userService3");
        ctx.close();
    }
}

修改非单例模式测试(自行测试)

这里有一点需要注意一下

scope="singleton" 时候,Spring容器中有且只有一个容器,init方法只会执行一次
scope="prototype" 时候,Spring容器要创建同一类型的多个对象,init方法在每个对象创建的时候均执行一次
scope="singleton" 时候,关闭容器会导致bean实例的小鬼,调用destroy方法一次
scope="prototype" 时候,对象的销毁均有垃圾回收机制gc()控制,destroy方法将不会被执行

4.bean对象创建的方式

名称:factory-bean,factory-method
类型:属性
归属:bean标签
作用:定义bean对象创建方式,使用实例工程的形式创建bean,兼容早期遗留系统的升级工作
格式:
<bean factory-bean="factoryBeanId" factory-method="factoryMethodName"></bean>
取值:工厂Bean中用于获取对象的实例方法名
注意事项:
    使用实例工厂创建bean首先需要将实例工厂配置Bean,交由Spring容器管理
    factory-bean是实例工厂的beanId

创建一个简单的工厂类

package com.xmaven.service;

import com.xmaven.service.impl.UserServiceImpl;

/**
 * @Author: Ambition
 * @Description TODO
 * @Date: 2021/3/7 1:39 下午
 * @Version 1.0
 */
public class UserServiceFactory {

    public static UserService getService(){
      	System.out.println("对象使用静态工厂创建出来了!");
        return new UserServiceImpl();
    }

}

修改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
        https://www.springframework.org/schema/beans/spring-beans.xsd">
    <!--1.创建Spring控制的资源-->
    <!--    <bean id="userService" name="service1,service2" class="com.xmaven.service.impl.UserServiceImpl"></bean>-->

    <!--判断是否是单例模式-->
    <!--<bean id="userService2" scope="singleton" class="com.xmaven.service.impl.UserServiceImpl"></bean>-->

    <!--init-method destroy-method 用于控制bean的生命周期-->
    <!--<bean id="userService3" scope="prototype" init-method="init" destroy-method="destroy" class="com.xmaven.service.impl.UserServiceImpl"></bean>-->

    <bean id="userService4" class="com.xmaven.service.UserServiceFactory" factory-method="getService"> </bean>
</beans>

测试代码

ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
UserService serivce4 = (UserService) ctx.getBean("userService4");

输出如下:

对象使用静态工厂创建出来了!
我是静态代码块
我是代码块
我是无参构造方法

上面使用的是静态工厂,如何使用实例工厂呢?

首先新建一个实例工厂

package com.xmaven.service;

import com.xmaven.service.impl.UserServiceImpl;

/**
 * @Author: Ambition
 * @Description TODO
 * @Date: 2021/3/7 1:39 下午
 * @Version 1.0
 */
public class UserServiceFactory2 {

    public UserService getService(){
        System.out.println("对象使用实例工厂创建出来了!");
        return new UserServiceImpl();
    }

}

在xml中添加

<!--注入实例工厂-->
<bean id="factoryBean" class="com.xmaven.service.UserServiceFactory2"/>

<bean id="userService5" factory-bean="factoryBean" factory-method="getService"/>

测试代码

ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
UserService serivce5 = (UserService) ctx.getBean("userService5");

注意注释xml中其他的代码 只留上面两行代码

输出:

对象使用实例工厂创建出来了!
我是静态代码块
我是代码块
我是无参构造方法

5.Spring中的DI

DI依赖注入,应用程序运行依赖由Spring为其提供基础,资源进入应用程序的方式称为注入。

6.依赖注入的两种方式

第一种Set注入(主流)

名称:property
类型:标签
归属:bean标签
作用:使用set方法的形式为bean提供资源
格式:
<bean>
	<property />
</bean>
基本属性:
<property name="propertyName" value="propertyValue" ref="beanId"/>
	name:对应bean中的属性名称,要求该属性必须提供可以访问的set方法(严格规范为此名称是set方法对应名称)
	value:设定非引用类型属性对应的值,不能与ref同时使用
	ref:设定引用类型属性对应bean的ID,不能和value同时使用

首先新建一个UserDao

package com.xmaven.dao;

/**
 * @Author: Ambition
 * @Description TODO
 * @Date: 2021/3/7 4:01 下午
 * @Version 1.0
 */
public interface UserDao {

    public void save();

}

编写相应的实现类

package com.xmaven.dao.impl;

import com.xmaven.dao.UserDao;

/**
 * @Author: Ambition
 * @Description TODO
 * @Date: 2021/3/7 4:01 下午
 * @Version 1.0
 */
public class UserDaoImpl implements UserDao {

    @Override
    public void save() {
        System.out.println("save............");
    }
}

到User ServiceImpl中实现

package com.xmaven.service.impl;

import com.xmaven.dao.UserDao;
import com.xmaven.service.UserService;

/**
 * @Author: Ambition
 * @Description TODO
 * @Date: 2021/3/7 12:05 下午
 * @Version 1.0
 */
public class UserServiceImpl implements UserService {

    private UserDao userDao;


    // 1.对需要进行注入的变量添加set方法
    public void setUserDao(UserDao userDao) {
        this.userDao = userDao;
    }

    @Override
    public void say() {
        System.out.println("run...");
        userDao.save();
    }
}

再去applicationContext.xml中注入

<bean id="userService" class="com.xmaven.service.impl.UserServiceImpl">
    <!--3.将要注入的引用类型的变量通过property属性进行注入,name是要注入的变量名,使用ref属性声明要注入bean-->
    <!--前面一个name 是Service中的UserDao的变量名 后面一个引用类型就是下面注入的bean的ID-->
    <property name="userDao" ref="userDao"/>
</bean>

<!--2.将要注入的资源声明为bean-->
<bean id="userDao" class="com.xmaven.dao.impl.UserDaoImpl"/>

然后在进行测试

package com.xmaven;

import com.xmaven.service.UserService;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

/**
 * @Author: Ambition
 * @Description TODO
 * @Date: 2021/3/7 4:14 下午
 * @Version 1.0
 */
public class UserApp2 {

    public static void main(String[] args) {
        ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
        UserService userService = (UserService) ctx.getBean("userService");
        userService.say();
    }

}

输出效果如下:

run...
save............

如果需要注入其他非引用类型的值就需要

直接在Bean中声明

<bean id="userService" class="com.xmaven.service.impl.UserServiceImpl">
    <!--3.将要注入的引用类型的变量通过property属性进行注入,name是要注入的变量名,使用ref属性声明要注入bean-->
    <!--前面一个name 是Service中的UserDao的变量名 后面一个引用类型就是下面注入的bean的ID-->
    <property name="userDao" ref="userDao"/>
    <property name="num" value="666"/>
</bean>

添加相应的变量和set方法

package com.xmaven.service.impl;

import com.xmaven.dao.UserDao;
import com.xmaven.service.UserService;

/**
 * @Author: Ambition
 * @Description TODO
 * @Date: 2021/3/7 12:05 下午
 * @Version 1.0
 */
public class UserServiceImpl implements UserService {

    private UserDao userDao;

    private int num;

    public void setNum(int num) {
        this.num = num;
    }

    // 1.对需要进行注入的变量添加set方法
    public void setUserDao(UserDao userDao) {
        this.userDao = userDao;
    }

    @Override
    public void say() {
        System.out.println("run..." + num);
        userDao.save();
    }
}

输出测试:

run...666
save............

包装 类型也要当成非引用类型来看待 如Integer Float Double …等等

set注入
		封装中的set方法
		bean中使用priperty标签注入属性
		name表示注入的属性名
		对象:使用ref进行注入
		其他:使用value进行注入

第二种构造器注入

名称:constructor-arg
类型:标签
归属:bean标签
作用:使用构造方法的形式为bean提供资源,兼容早期遗留系统升级工作
格式:
<bean>
		<constructor-arg/>
</bean>
基本属性:
<constructor-arg name="argsName" value="argsValue"/>
	name:对应bean中的构造方法所携带的参数名
	value:设定非引用类型构造方法的参数对应的值,不能与ref同时使用
注意:一个bean可以有多个constructor-args标签

修改UserSerivce的实现类

package com.xmaven.service.impl;

import com.xmaven.dao.UserDao;
import com.xmaven.service.UserService;

/**
 * @Author: Ambition
 * @Description TODO
 * @Date: 2021/3/7 12:05 下午
 * @Version 1.0
 */
public class UserServiceImpl implements UserService {

    private UserDao userDao;


    public UserServiceImpl(UserDao userDao) {
        this.userDao = userDao;
    }


    @Override
    public void say() {
        System.out.println("run...");
        userDao.save();
    }
}

修改xml只要这两个bean

<bean id="userDao" class="com.xmaven.dao.impl.UserDaoImpl"/>
<bean id="userService5" class="com.xmaven.service.impl.UserServiceImpl">
   <constructor-arg ref="userDao"/>
</bean>

注入多个参数也需要添加对应的constructor-arg

UserServiceImpl中也需要添加对应的参数的构造方法

如下:

<bean id="userDao" class="com.xmaven.dao.impl.UserDaoImpl"/>
<bean id="userService5" class="com.xmaven.service.impl.UserServiceImpl">
   <constructor-arg ref="userDao"/>
    <constructor-arg  name="num" value="666"/>
</bean>
package com.xmaven.service.impl;

import com.xmaven.dao.UserDao;
import com.xmaven.service.UserService;

/**
 * @Author: Ambition
 * @Description TODO
 * @Date: 2021/3/7 12:05 下午
 * @Version 1.0
 */
public class UserServiceImpl implements UserService {

    private UserDao userDao;

    private int num;

    public UserServiceImpl(UserDao userDao, int num) {
        this.userDao = userDao;
        this.num = num;
    }


    @Override
    public void say() {
        System.out.println("run..." + num);
        userDao.save();
    }
}

可以在constructor-arg中添加index属性这个属性用于标记参数的位置,记住参数是从0开始的

不建议用index有的时候index需要全部都改

构造器注入:
		带参构造方法
		bean中使用constructor-arg标签注入属性
		name表示注入的属性名称  强烈建议 可拓展性好
		对象:使用ref进行注入
		其他:使用value注入
		支持按类型注入 使用type 不建议
		支持顺序注入 不建议

7.集合类型数据注入

名称:array list set map props
类型:标签
归属:property标签或constructor-arg标签
作用:注入集合数据类型属性
格式:
<property>
		<list></list>
</property>

新建一个Book Service

package com.xmaven.test2.service;

/**
 * @Author: Ambition
 * @Description TODO
 * @Date: 2021/3/7 4:59 下午
 * @Version 1.0
 */
public interface BookService {
    public void save();
}

新建一个他的实现类

package com.xmaven.test2.service.impl;

import com.xmaven.test2.service.BookService;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Properties;

/**
 * @Author: Ambition
 * @Description TODO
 * @Date: 2021/3/7 4:59 下午
 * @Version 1.0
 */
public class BookServiceImpl implements BookService {

    private ArrayList al;

    private Properties properties;

    private String[] arr;

    private HashSet hs;

    private HashMap hm;

    public void setAl(ArrayList al) {
        this.al = al;
    }

    public void setProperties(Properties properties) {
        this.properties = properties;
    }

    public void setArr(String[] arr) {
        this.arr = arr;
    }

    public void setHs(HashSet hs) {
        this.hs = hs;
    }

    public void setHm(HashMap hm) {
        this.hm = hm;
    }

    @Override
    public void save() {
        System.out.println("bookService run---------");
        System.out.println("ArrayList:"+al);
        System.out.println("Properties:"+properties);
        for (String i : arr) {
            System.out.println(i);
        }
        System.out.println("HashSet:"+hs);
        System.out.println("HashMap:"+hm);
    }
}

修改UserServiceImpl

package com.xmaven.service.impl;

import com.xmaven.dao.UserDao;
import com.xmaven.service.UserService;
import com.xmaven.test2.service.BookService;

/**
 * @Author: Ambition
 * @Description TODO
 * @Date: 2021/3/7 12:05 下午
 * @Version 1.0
 */
public class UserServiceImpl implements UserService {

    private UserDao userDao;

    private int num;

    private BookService bookService;

    public UserServiceImpl(UserDao userDao, int num,BookService bookService) {
        this.userDao = userDao;
        this.num = num;
        this.bookService = bookService;
    }


    @Override
    public void say() {
        System.out.println("run..." + num);
        userDao.save();
        bookService.save();
    }
}

xml中只需留下一下内容

<bean id="userDao" class="com.xmaven.dao.impl.UserDaoImpl"/>
<bean id="bookService" class="com.xmaven.test2.service.impl.BookServiceImpl">
    <property name="al">
        <list>
            <value>ambition</value>
            <value>6666</value>
        </list>
    </property>
    <property name="properties">
        <props>
            <prop key="name">ambition</prop>
            <prop key="value">66666</prop>
        </props>
    </property>
    <property name="arr">
        <array>
            <value>ambition</value>
            <value>6666</value>
        </array>
    </property>
    <property name="hs">
        <set>
            <value>ambition</value>
            <value>6666</value>
        </set>
    </property>
    <property name="hm">
        <map>
            <entry key="name" value="ambition666"/>
            <entry key="value" value="6666666"/>
        </map>
    </property>
</bean>
<bean id="userService5" class="com.xmaven.service.impl.UserServiceImpl">
    <constructor-arg ref="userDao"/>
    <constructor-arg name="num" value="666"/>
    <constructor-arg name="bookService" ref="bookService"/>
</bean>

编写测试类

package com.xmaven;

import com.xmaven.service.UserService;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

/**
 * @Author: Ambition
 * @Description TODO
 * @Date: 2021/3/7 4:14 下午
 * @Version 1.0
 */
public class UserApp2 {

    public static void main(String[] args) {
        ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
        UserService userService = (UserService) ctx.getBean("userService5");
        userService.say();
    }

}

输出结果如下:

run...666
save............
bookService run---------
ArrayList:[ambition, 6666]
Properties:{name=ambition, value=66666}
ambition
6666
HashSet:[ambition, 6666]
HashMap:{name=ambition666, value=6666666}

8.使用p命名空间简化配置(了解)

名称:p:propertyName p:propertyName-ref
类型:属性
归属:bean标签
作用;为bean注入属性值
格式 :
<bean p:propertyName="propertyValue" p:propertyName-ref="beanId"/>
注意:使用p命名空间需要先开启spring对p空间的支持,在beans标签中添加对应空间的支持
<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
        https://www.springframework.org/schema/beans/spring-beans.xsd">

例如原来bean标签写法

<bean id="userDao" class="com.xmaven.dao.impl.UserDaoImpl">
	<property name="useDao" ref="userDa0"/> 
	<property name="bookDao" ref="bookDao"/> 
</beans>

可以修改为:

<bean id="userDao" class="com.xmaven.dao.impl.UserDaoImpl" p:useDao-ref="userDa0" p:bookDao-ref="bookDao" /> 

目的是为了简化书写

9.SpEL(了解)

Spring提供了对EL表达式的支持
类型:属性值
归属:value属性值
作用:为bean注入属性值
格式:
<property value="EL"></property>
注意所有属性值不区分是否引用类型,统一使用value赋值

image-20210307174545762.png

这里就不演示了。

10.读取Properties文件信息

properties文件

Spring提供了读取外部properties文件的机制,使用读取到的数据为bean的属性赋值

操作步骤:

​ 1.准备外部properties文件

​ 2.开启context命名空间的支持

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

​ 3.加载指定的properties文件

<context:property-placeholder location="classpath:data.properties"/>

​ 4.使用加载的数据

注意:如果需要加载所有的properties文件,可以使用*.properties表示加载所有的properties文件

注意:读取数据使用${propertiesName}格式,其中propertiesName指的是properties文件中的属性名称

使用UserDao为例

package com.xmaven.dao.impl;

import com.xmaven.dao.UserDao;

/**
 * @Author: Ambition
 * @Description TODO
 * @Date: 2021/3/7 4:01 下午
 * @Version 1.0
 */
public class UserDaoImpl implements UserDao {

    private String userName;

    private String password;

    public void setUserName(String userName) {
        this.userName = userName;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    @Override
    public void save() {
      	System.out.println("userName=" + userName + " " + "password=" + password);
        System.out.println("save............");
    }
}

编写一个data.properties

username=ambition
pass=123

xml中添加

<context:property-placeholder location="classpath:data.properties"/>

<bean id="userDao" class="com.xmaven.dao.impl.UserDaoImpl">
    <property name="userName" value="${username}"/>
    <property name="password" value="${pass}"/>
</bean>

测试输出

userName=ambition password=123

11.import导入配置文件

团队开发
名称:import
类型:标签
归属:beans标签
作用:在当前配置文件中导入其他配置文件中的项
格式:
<beans>
			<import />
</beans>
基本属性:
<import resource="config.xml"/>
resource:加载配置的文件名

image-20210307210259336.png

Spring容器加载多个配置文件

new ClassPathXmlApplicationContext("applicationContext-user.xml","applicationContext-book.xml");

Spring容器中的bean定义冲突问题

​ 同id的bean,后定义的覆盖先定义的

​ 导入配置文件可以理解为将导入的配置文件复制粘贴到对应位置

​ 导入配置文件的顺序与位置不同可能会导致最终程序运行结果不同

12.ApplicationContext对象层次结构

image-20210307211328472.png

image-20210307211353504.png

ApplicationContext

1.ApplicationContext是一个接口,提供了访问Spring的API

2.ClassPathXmlApplicationContext是一个类,实现了上述功能

3.ApplicationContext的顶层接口是BeanFactory

4.BeanFactory定义了bean的相关操作

5.ApplicationContext在BeanFactory基础上追加了若干新功能

对比BeanFactory

1.BeanFactory创建的bean采用延迟加载的形式,使用才创建

2.ApplicationContext创建的bean默认是采用立即加载的形式

FileSystemXmlApplicationContext

可以加载文件系统中任意位置的配置文件,而ClassPathXmlApplicationContext只能加载类路径下面的配置文件

image-20210307212244949.png

13.带三方Bean的配置方式

第三方资源配置

例如注入三方连接池

<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
    <property name="driverClassName" value="com.mysql.jdbc.Driver"/>
    <property name="url" value="jdbc:mysql://localhost:3306/spring_db"/>
    <property name="username" value="root"/>
    <property name="password" value="root"/>
</bean>
0

评论区