spring IoC详解

spring IoC详解

1.spring是什么?

众多开源 java 项目中的一员,基于分层的 javaEE 应用一站式轻量级开源框架,主要核心是 Ioc(控制反转/依赖注入) 与 Aop(面向切面)两大技术,实现项目在开发过程中的轻松解耦,提高项目的开发效率。

2.为什么要使用spring

轻量:Spring 是轻量的,基本的版本大约2MB。

控制反转:Spring通过控制反转实现了松散耦合,对象们给出它们的依赖,而不是创建或查找依赖的对象们。

面向切面的编程(AOP):Spring支持面向切面的编程,并且把应用业务逻辑和系统服务分开。

** 容器:** Spring 包含并管理应用中对象的生命周期和配置。

** 事务管理:** Spring 提供一个持续的事务管理接口,可以扩展到上至本地事务下至全局事务(JTA)

** 异常处理:** Spring 提供方便的API把具体技术相关的异常(比如由JDBC,Hibernate or JDO抛出的)转化为一致的unchecked 异常。

降低耦合
/**
 * 程序的耦合
 *      耦合:程序间的依赖关系
 *          包括:
 *              类之间的依赖
 *              方法间的依赖
 *      解耦:
 *          降低程序间的依赖关系
 *      实际开发中:
 *          应该做到:编译期不依赖,运行时才依赖。
 *      解耦的思路:
 *          第一步:使用反射来创建对象,而避免使用new关键字。
 *          第二步:通过读取配置文件来获取要创建的对象全限定类名
 */
spring 的两个重要概念:ioc,aop

很多对象,肯定要找个集合来存,有查找需求,这个 map 称之为容器

new 的方式。是主动的。有工厂为我们查找或者创建对象。是被动的。种被动接收的方式获取对象的思想就是控制反转,它是 spring 框架的核心之一。

明确 ioc 的作用:
削减计算机程序的耦合(解除我们代码中的依赖关系)。

spring5 版本是用 jdk8 编写的,所以要求我们的 jdk 版本是 8 及以上。
同时 tomcat 的版本要求 8.5 及以上。

了解:xml文档都有格式,为了spring的配置文件增加的节点能满足要求、合法,所以引入校验该xml的格式文件。
xmlns是xml命名空间的意思,而xmlns:xsi是指xml所遵守的标签规范。
1.xmlns:关于初始化bean的格式文件地址
2.xmlns:xsi:辅助初始化bean
3.xsi:context:关于spring上下文,包括加载资源文件
4.xsi:schemaLocation:用于声明了目标名称空间的模式文档

配置service,即创建对象放在容器中,
在xml的配置为(使用xml配置需要在接口的实现类中若有属性,则需有有set方法,注解则不需要。所以在配置时,推荐使用注解,注意注解就需要开启扫描)

使用注解: 有接口,还要有实现类,在实现类上加注解

3.搭建spring-maven环境

3.1 创建一个maven的普通工程 quickstart

3.2 引用pom.xml依赖

<?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.shsxt</groupId>
  <artifactId>spring02</artifactId>
  <version>1.0-SNAPSHOT</version>

  <name>spring02</name>
    
  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <maven.compiler.source>1.8</maven.compiler.source>
    <maven.compiler.target>1.8</maven.compiler.target>
  </properties>

  <dependencies>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.12</version>
      <scope>test</scope>
    </dependency>
    
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-context</artifactId>
      <version>4.3.9.RELEASE</version>
    </dependency>
  </dependencies>

  <build>
    </build>
</project>

3.3 创建一个bean

UserDao.java
package com.shsxt.dao;

public class UserDao {
	 public void add(String name, Integer passpwd){
		System.out.println("add:"+name+" "+passpwd);
    }
}
HelloService.java
package com.shsxt.service;

public class HelloService {

    public void hello(){
        System.out.println("hello spring");
    }
}

3.4 创建一个spring.xml配置文件,配置bean

spring02.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
http://www.springframework.org/schema/beans/spring-beans.xsd">
<!--
xmlns 即 xml namespace xml 使用的命名空间
xmlns:xsi 即 xml schema instance xml 遵守的具体规范
xsi:schemaLocation 本文档 xml 遵守的规范 官方指定
-->
    
<bean id="helloService" class="com.shsxt.service.HelloService"></bean>
<bean id="userDao" class="com.shsxt.dao.UserDao"></bean>
</beans>

3.5 单元测试 junit

package com.shsxt;

import com.shsxt.service.HelloService;
import org.junit.Test;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class TestSpring {

    @Test
    public void test01(){
        ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("spring02.xml");

        HelloService helloService = (HelloService) context.getBean("helloService");

        helloService.hello();
    }
}

4.spring容器的简单实现

应用技术:

xml解析
xpath使用
dom4j
反射
集合

具体步骤

1.读取xml配置文件
2.通过配置信息创建类的实例
3.存储实例以及取出实例
注意: 配置文件中 不能引用外部网站
代码体现:

4.1 引入相关依赖

<?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.shsxt</groupId>
  <artifactId>spring03</artifactId>
  <version>1.0-SNAPSHOT</version>

  <name>spring03</name>


  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <maven.compiler.source>1.8</maven.compiler.source>
    <maven.compiler.target>1.8</maven.compiler.target>
  </properties>

  <dependencies>

    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.12</version>
      <scope>test</scope>
    </dependency>

    <dependency>
      <groupId>dom4j</groupId>
      <artifactId>dom4j</artifactId>
      <version>1.6.1</version>
    </dependency>
    <dependency>
      <groupId>jaxen</groupId>
      <artifactId>jaxen</artifactId>
      <version>1.1.6</version>
    </dependency>

  </dependencies>

  <build>
  </build>
</project>

4.2 配置spring全局配置文件

spring03.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans>
	<bean id="userDao" class="dao.UserDao"></bean>
</beans>

4.3 创建java类

package dao;

public class UserDao {
    
    public void userDao(){
        System.out.println("helle");
    }
}

4.4 创建接口,获取bean实例的接口

public interface ApplicationContext {

    public Object getBean(String id);

}

4.5 创建实现类

package com.shsxt;

import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;

import java.net.URL;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class SxtApplicationContext implements ApplicationContext {

    /**
     * 1.读取xml配置文件
     * 2.生成Bean实例
     * 3.取出bean
     * @param id
     * @return
     */
    private String path;

    private List<SxtBean> beanList = new ArrayList<>();

    private Map<String,Object> map = new HashMap<>();

    public SxtApplicationContext(String path) {
        this.path = path;
        parseXml(path);
        createBean();
    }

    /**
     * 取出bean
     * @param id
     * @return
     */
    public Object getBean(String id){

        return map.get(id);
    }


    /**
     * 生成相应的Bean
     */
    private void createBean() {
       if (beanList!=null && beanList.size()>0){
           for (SxtBean sxtBean: beanList){
               try {
              map.put(sxtBean.getId(),Class.forName(sxtBean.getClazz()).newInstance());
               } catch (InstantiationException e) {
                   e.printStackTrace();
               } catch (IllegalAccessException e) {
                   e.printStackTrace();
               } catch (ClassNotFoundException e) {
                   e.printStackTrace();
               }
           }
       }

    }


    /**
     * 解析配置文件xml
     * @param path
     */
    private void parseXml(String path) {
        SAXReader reader = new SAXReader();
        if (null!=path && !"".equals(path)){

            URL url = this.getClass().getClassLoader().getResource(path);
            try {
                Document document = reader.read(url);
                List<Element> list = document.selectNodes("//beans/bean");
                for (Element element:list){
                    SxtBean sxtBean = new SxtBean();
                    sxtBean.setId(element.attributeValue("id"));
                    sxtBean.setClazz(element.attributeValue("class"));
                    beanList.add(sxtBean);
                }
            } catch (DocumentException e) {
                e.printStackTrace();
            }

        }else {
            System.out.println("文件不存在");
        }
    }
}

4.6 用到的vo 类

SxtBean.java
package com.shsxt;

public class SxtBean {

    private String id;    //xml中对应的 id属性
    private String clazz; //xml中对应的 class属性

    public String getClazz() {
        return clazz;
    }

    public void setClazz(String clazz) {
        this.clazz = clazz;
    }

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }
}

4.7 测试

package com.shsxt;

import dao.UserDao;
import org.junit.Test;

import static org.junit.Assert.*;

public class ContextTest {

    @Test
    public void test(){
        ApplicationContext context = new SxtApplicationContext("spring03.xml");

        UserDao userDao = (UserDao) context.getBean("userDao");

        userDao.userDao();
    }
}

5.Spring 多文件加载情况

Spring 框架启动时可以加载多个配置文件到环境中。对于比较复杂的项目,可能对应
的配置文件有多个,项目在启动部署时会将多个配置文件同时加载进来

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

    <bean id="userDao" class="com.shsxt.dao.UserDao"></bean>
</beans>
Service.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
http://www.springframework.org/schema/beans/spring-beans.xsd">

    <bean id="userService" class="com.shsxt.service.UserService"></bean>
</beans>
Controller.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
http://www.springframework.org/schema/beans/spring-beans.xsd">

    <bean id="userController"
class="com.shsxt.comtroller.UserController"></bean>
</beans>
测试
@Test
public void test01() throws Exception{
    ApplicationContext ac=new
    ClassPathXmlApplicationContext("dao.xml","service.xml","controller.xml");
    // 获取 dao 层 bean
    UserDao userDao=(UserDao) ac.getBean("userDao");
    userDao.save();
    //获取 service 层 bean
    UserService userService= (UserService) ac.getBean("userService");
    userService.hello();
    // 获取 controller bean
    UserController userController=(UserController)
    ac.getBean("userController");
    userController.show();
}

6.Spring IoC 实例化 bean对象的三种方式

6.1 构造器的方式实例化bean对象

<bean id="userServiceImpl"
		class="com.shsxt.service.impl.UserServiceImpl">
</bean>

通过默认构造器创建 空构造方法必须存在 否则创建失败

6.2 静态工厂方法方式实例化 bean

1.要有该工厂类及工厂方法
2.工厂方法为静态的

静态工厂定义
package com.shsxt.factory;
import com.shsxt.service.UserService;
public class StaticFactory {
    public static UserService createUserService(){
        return new UserService();
    }
}
Bean配置
<bean id="userService" class="com.shsxt.factory.StaticFactory"
		factory-method="createUserService"/>

当我们指定 Spring 使用静态工厂方法来创建 Bean 实例时,Spring 将先解析配置文件,并根据配置文件指定的信息,通过反射调用静态工厂类的静态工厂方法,并将该静态工厂方法的返回值作为 Bean 实例,在这个过程中,Spring 不再负责创建 Bean 实例,Bean 实例是由用户提供的静态工厂方法提供的.

6.3 实例化工厂方式创建Bean

相比较静态工厂实现
I.工厂方法为非静态方法

II.需要配置工厂 bean,并在业务 bean 中配置 factory-bean,factory-method 属性

实例化工厂定义
package com.shsxt.factory;
import com.shsxt.service.UserService;
public class InstanceFactory {
    public UserService createUserService(){
    	return new UserService();
    }
}
Bean配置
<!--实例化工厂
1.定义实例化工厂 bean
2.引用工厂 bean 指定工厂创建方法(方法为非静态)
-->
<bean id="instanceFactory" class="com.shsxt.factory.InstanceFactory"></bean>
<bean id="userService" factory-bean="instanceFactory" 		     
      		factory-method="createUserService">
</bean>

6.4 spring 三种实例化 bean 的方式比较

方式一:

通过 bean 的缺省构造函数创建,当各个 bean 的业务逻辑相互比较独立的时
候或者和外界关联较少的时候可以使用

方式二:

利用静态 factory 方法创建,可以统一管理各个 bean 的创建,如各个 bean 在
创建之前需要相同的初始化处理,则可用这个 factory 方法险进行统一的处理等等

方式三:

利用实例化 factory 方法创建,即将 factory 方法也作为了业务 bean 来控制,
1 可用于集成其他框架的 bean 创建管理方法,2 能够使 bean 和 factory 的角色互换。

开发中项目一般使用一种方式实例化 bean,项目开发基本采用第一种方式,交
给 spring 托管,使用时直接拿来使用即可

7.Spring 依赖注入(Dependency Injection 即 DI)

Spring 支持的注入方式:set注入,构造器注入,静态工厂注入, 实例化工厂注入

7.1 Set注入

xml配置(支持基本数据类型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"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="userServiceImpl" class="com.shsxt.service.impl.UserServiceImpl">
	<property name="userDao" ref="userDao"></property>
</bean>
<bean id="userDao" class="com.shsxt.dao.UserDao"></bean>
</beans>
Java类
package com.shsxt.service.impl;
import com.shsxt.dao.UserDao;
import com.shsxt.vo.User;
public class UserServiceImpl {
    private UserDao userDao;
    public void setUserDao(UserDao userDao) {
    	this.userDao = userDao;
    }
    public UserDao getUserDao() {
   		return userDao;
    }
    public void saveUser(User user){
    	System.out.println("userName:"+userName+"price:"+price);
    	userDao.add(user);
    }
}
基本数据类型set注入
<bean id="userServiceImpl" class="com.shsxt.service.impl.UserServiceImpl">
	<property name="userDao" ref="userDao"></property>
	<property name="userName" value="sxt"></property>
	<property name="price" value="123"></property>
</bean>

同时对应 Service 提供对应属性字段 以及 get 、set 方法即可

7.2 构造器注入

xml配置(也提供对于基本数据类型,字符串等值的注入)
<bean id="userDao" class="com.shsxt.dao.UserDao"></bean>
<bean id="userServiceImpl2"  class="com.shsxt.service.impl.UserServiceImpl2">
	<constructor-arg ref="userDao"></constructor-arg>
</bean>
Java类提供构造函数
package com.shsxt.service.impl;
import com.shsxt.dao.UserDao;
import com.shsxt.vo.User;
public class UserServiceImpl2 {
    private UserDao userDao;
    public UserServiceImpl2(UserDao userDao) {
    	this.userDao = userDao;
    }
    public void saveUser(User user){
    	userDao.add(user);
	}
}
构造器注入字符串值

Index 属性为参数顺序 如果只有一个参数 index 可以不设置

<bean id="userServiceImpl" class="com.shsxt.service.impl.UserServiceImpl">
	<constructor-arg name="userName" index="0" value="123"></constructor-arg>
	<constructor-arg name="userPwd" index="1" value="321"></constructorarg>
</bean>

7.3 静态工厂注入

xml配置
<bean id="userDao" class="com.shsxt.factory.StaticFactory" 
      factory-method="createUserDao"></bean>
<bean id="userService" class="com.shsxt.service.UserService">
	<property name="userDao" ref="userDao"></property>
</bean>
java类
package com.shsxt.factory;
import com.shsxt.dao.UserDao;
public class StaticFactory {
    public static UserDao createUserDao(){
    	return new UserDao();
    }
}

和set注入的区别只是获取bean的方式不同

7.4 实例化工厂

和set注入的区别只是获取bean的方式不同

7.5 p标签和 c标签

<!-- 简化set注入 -->
xmlns:p="http://www.springframework.org/schema/p"
<bean id="userDao" class="com.shsxt.dao.UserDao"></bean>
<bean id="userService" class="com.shsxt.service.UserService"
	p:userDao-ref="userDao"
	p:age="20"
	p:uname="sxt"
> </bean>
<!-- 简化构造器注入 -->
xmlns:c="http://www.springframework.org/schema/c"
<bean id="userService" class="com.shsxt.service.UserService"
	c:userDao-ref="userDao"
	c:age="20"
	c:uname="sxt"
/>

7.6 集合注入

list集合注入
<bean id="userServiceImpl" class="com.shsxt.service.impl.UserServiceImpl">
	<property name="list">
		<list>
            <value>河南烩面</value>
            <value>南方臊子面</value>
            <value>油泼面</value>
            <value>方便面</value>
		</list>
	</property
</bean>
set集合注入
<bean id="userServiceImpl"
class="com.shsxt.service.impl.UserServiceImpl">
    <property name="set">
        <set>
            <value>快乐小馒头</value>
            <value>北方馒头</value>
            <value>天津麻花</value>
            <value>新疆大饼</value>
        </set>
    </property>
</bean>
map类型属性注入
<bean id="userServiceImpl" class="com.shsxt.service.impl.UserServiceImpl">
    <property name="map">
        <map>
            <entry>
                 <key><value>河南</value></key>
                 <value>云台山风景</value>
             </entry>
            <entry>
                <key><value>上海</value></key>
                <value>宝塔</value>
            </entry>
            <entry>
                <key><value>北京</value></key>
                <value>紫禁城</value>
            </entry>
        </map>
    </property>
</bean>
properties属性注入
<bean id="userServiceImpl"
class="com.shsxt.service.impl.UserServiceImpl">
    <property name="prop">
        <props>
            <prop key="北京">北京尚学堂</prop>
            <prop key="上海">上海尚学堂</prop>
            <prop key="西安">西安尚学堂</prop>
        </props>
    </property>
</bean>

8.注解方式注入bean

注解的配置简化开发的速度,使程序看上去更简洁。
在这里插入图片描述

8.1 加入 spring-aop jar 包 spring-aop-4.3.2.RELEASE.jar

8.2 Xml 配置: 加入 context 命名空间 和 xsd 地址

8.3 添加<context:annotation-config/ >配置

<?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
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">
	<context:annotation-config/>
</beans>

对于 bean 的注入常用注解类型

@Autowired 属性字段或 set 方法上
@Resource 属性字段上或 set 方法上

相当于:<bean id="" class="" scope="">
@Autowired
作用:
自动按照类型注入。当使用注解注入属性时,set 方法可以省略。它只能注入其他 bean 类型。当有多个
类型匹配时,使用要注入的对象变量名称作为 bean 的 id,在 spring 容器查找,找到了也可以注入成功。找不到
就报错。
@Qualifier
作用:
在自动按照类型注入的基础之上,再按照 Bean 的 id 注入。它在给字段注入时不能独立使用,必须和@Autowire 一起使用;但是给方法参数注入时,可以独立使用。
属性:
value:指定 bean 的 id。
@Resource
作用:
直接按照 Bean 的 id 注入。它也只能注入其他 bean 类型。
属性:
name:指定 bean 的 id。
@Value
作用:
注入基本数据类型和 String 类型数据的
属性:
value:用于指定值

用于改变作用范围的:
相当于:<bean id="" class="" scope="">
@Scope
作用:
指定 bean 的作用范围。
属性:
value:指定范围的值。
取值:singleton
prototype request session globalsession

8.4 注解区别

@Autowired 默认按 bean 的类型匹配 可以修改 按名称匹配 和@Qualifier 配合使用

@Resource 默认按名称进行装配,名称可以通过 name 属性进行指定,如果没有指定 name 属性,当注解写在字段上时,默认取字段名进行匹配注入,如果注解写在 setter 方法上默认取属性名进行装配。当找不到与名称匹配的 bean时才按照类型进行装配。但是需要注意的是,如果 name 属性一旦指定,就只会按照名称进行装配。

推荐使用@Resource 注解是属于 J2EE 的,减少了与 spring 的耦合

8.5 新注解

@Configuration

作用:
用于指定当前类是一个 spring 配置类,当创建容器时会从该类上加载注解。获取容器时需要使用AnnotationApplicationContext(有@Configuration 注解的class)。
属性:
value:用于指定配置类的字节码
实例:
spring 的配置类

	@Configuration
		public class SpringConfiguration {
	}

注意:
我们已经把配置文件用类来代替了,但是如何配置创建容器时要扫描的包呢?
请看下一个注解。

@ComponentScan

作用:
用于指定 spring 在初始化容器时要扫描的包。作用和在 spring 的 xml 配置文件中的:<context:component-scan base-package=“com.itheima”/>是一样的。
属性:basePackages:用于指定要扫描的包。和该注解中的 value 属性作用一样。

@Configuration
@ComponentScan("com.itheima")
public class SpringConfiguration {
}

注意:
我们已经配置好了要扫描的包,但是数据源和 JdbcTemplate 对象如何从配置文件中移除呢?
请看下一个注解。

@Bean

作用:
该注解只能写在方法上,表明使用此方法创建一个对象,并且放入 spring 容器。
属性:
name:给当前@Bean 注解方法创建的对象指定一个名称(即 bean 的 id)。

连接数据库的配置类

public class JdbcConfig {
	/**
	* 创建一个数据源,并存入 spring 容器中
	*/
	@Bean(name="dataSource")
	public DataSource createDataSource() {
		try {
			ComboPooledDataSource ds = new ComboPooledDataSource();
			ds.setUser("root");
			ds.setPassword("1234");
			ds.setDriverClass("com.mysql.jdbc.Driver");
			ds.setJdbcUrl("jdbc:mysql:///spring_day02");
			return ds;
		} catch (Exception e) {
			throw new RuntimeException(e);
		}
	}
	/**
	* 创建一个 DBAssit,并且也存入 spring 容器中
	*/
	@Bean(name="dbAssit")
	public DBAssit createDBAssit(DataSource dataSource) {
		return new DBAssit(dataSource);
	}
}

注意:
我们已经把数据源和 DBAssit 从配置文件中移除了,此时可以删除 bean.xml 了。
但是由于没有了配置文件,创建数据源的配置又都写死在类中了。如何把它们配置出来呢?
请看下一个注解。

@PropertySource

作用:
用 于 加载 .properties 文件 中的 配置 。 例如 我们 配置 数据 源时 , 可以 把连 接数 据库 的信 息 写 到
properties 配置文件中,就可以使用此注解指定 properties 配置文件的位置。
属性:
value[]:用于指定 properties 文件位置。如果是在类路径下,需要写上 classpath:

配置:

/**
* 连接数据库的配置类
*/
public class JdbcConfig {
	@Value("${jdbc.driver}")
	private String driver;
	
	@Value("${jdbc.url}")
	private String url;
	
	@Value("${jdbc.username}")
	private String username;
	
	@Value("${jdbc.password}")
	private String password;
	/**
	* 创建一个数据源,并存入 spring 容器中
	*/
	@Bean(name="dataSource")
	public DataSource createDataSource() {
		try {
			ComboPooledDataSource ds = new ComboPooledDataSource();
			ds.setDriverClass(driver);
			ds.setJdbcUrl(url);
			ds.setUser(username);
			ds.setPassword(password);
			return ds;
		} catch (Exception e) {
			throw new RuntimeException(e);
		}
	}
}

jdbc.properties 文件:

jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/spring
jdbc.username=zheng
jdbc.password=123456

注意:
此时我们已经有了两个配置类,但是他们还没有关系。如何建立他们的关系呢?
请看下一个注解。

@Import

作用:
用于导入其他配置类,在引入其他配置类时,可以不用再写@Configuration 注解。当然,写上也没问
题。
属性:
value[]:用于指定其他配置类的字节码。
示例代码:

@Configuration
@ComponentScan(basePackages = "com.test.spring")
@Import({ JdbcConfig.class})
public class SpringConfiguration {
}
@Configuration
@PropertySource("classpath:jdbc.properties")
public class JdbcConfig{
}

注意:
我们已经把要配置的都配置好了,但是新的问题产生了,由于没有配置文件了,如何获取容器呢?
通过注解获取容器:

    ApplicationContext ac = new AnnotationConfigApplicationContext(SpringConfiguration.class);

9.Spring IoC 容器自动扫描管理 bean

//自动扫描  com.shsxt下的所有类
<context:component-scan base-package="com.shsxt"/>

同时对于被 spring 管理的 bean 类的定义上需要加入对应的注解定义

Dao层:@Repository

Service层:@Service

视图控制层: @Controller

如果对于开发的类实在不明确到底属于哪个层,可以使用@Component 注解定义

10.Bean 的作用域

容器中的对象要注意,有单例类,和多例类之分
单例对象:scope=“singleton”
一个应用只有一个对象的实例。它的作用范围就是整个引用。
生命周期:
对象出生:当应用加载,创建容器时,对象就被创建了。
对象活着:只要容器在,对象一直活着。
对象死亡:当应用卸载,销毁容器时,对象就被销毁了。

多例对象:scope=“prototype”
每次访问对象时,都会重新创建对象实例。
生命周期:
对象出生:当使用对象时,创建新的对象实例。
对象活着:只要对象在使用中,就一直活着。
对象死亡:当对象长时间不用时,被 java 的垃圾回收器回收了。

10.1 singleton 作用域 (默认设置是单例)

<bean id="bean" class="...." lazy-init="true"></bean>

注意: lazy-init 是懒加载, 如果等于 true 时作用是指 spring 容器启动的时候不会去实例化这个 bean, 而是在程序调用时才去实例化. 默认是 false 即 spring 容器启动时实例化

容器在启动的情况下就实例化所有 singleton 的 bean 对象,并缓存与容器中

单例的好处:

1)提前发现潜在的配置问题

2)Bean 对象存在于缓存中,使用时不用再去实例化 bean,加快程序运行效率

一般来说对于无状态或状态不可改变的 对象适合使用单例模式(什么是无状态或状态
不可改变)

10.2 prototype 作用域

<bean id="bean" class="..." scope="prototype"></bean>

通过 scope=” prototype” 设置 bean 的类型 ,每次向 Spring 容器请求获取Bean 都返回一个全新的 Bean,相对于“singleton”来说就是不缓存 Bean,每次都是一个根据 Bean 定义创建的全新 Bean。

10.3 Web 应用中的作用域(request、session、globalsession)

request 作用域:表示每个请求需要容器创建一个全新 Bean。比如提交表单的数据必须是对每次请求新建一个 Bean 来保持这些表单数据,请求结束释放这些数据。

session 作用域:表示每个会话需要容器创建一个全新 Bean。比如对于每个用户一般会有一个会话,该用户的用户信息需要存储到会话中,此时可以将该 Bean 作用域配置为 session 级别。

globalSession:类似于 session 作用域,其用于 portlet(Portlet 是基于 Java的 Web 组件,由 Portlet 容器管理,并由容器处理请求,生产动态内容)环境的 web 应用。如果在非 portlet 环境将视为 session 作用域。

11.Bean的生命周期

11.1 Bean 的定义

对比 servlet 生命周期(容器启动装载并实例化 servlet 类,初始化servlet,调用 service 方法,销毁 servlet)。同样对于 spring 容器管理的 bean 也存在生命周期的概念。

Bean的Java类的创建就是Bean的定义

11.2 Bean的初始化

Spring bean 初始化有两种方式:

I.在配置文档中通过指定 init-method 属性来完成

II.实现 org.springframework.beans.factory.InitializingBean 接口。

<bean id="userServiceImpl"class="com.shsxt.service.impl.UserServiceImpl"
      init-method="init" >

11.3 Bean 的使用

I.使用 BeanFactory

II.使用 ApplicationContext

11.4 Bean 的销毁

实现销毁方式(spring 容器会维护 bean 对象的管理,可以指定 bean 对象的销毁所要执行的方法)

<bean id="userServiceImpl"class="com.shsxt.service.impl.UserServiceImpl" init-	method="init" destroy-method="destroy">
</bean>

通过 AbstractApplicationContext 对象,调用其 close 方法实现 bean 的销毁过程。

AbstractApplicationContext ctx = new ClassPathXmlApplicationContext("spring_application.xml");
ctx.close();

12 补充

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

13 注意

mysql版本出错

之前使用了mysql 8.0版本,结果连接不上数据库,换成5.1.47才好使。
jar包:mysql-connector-java

使用xml配置spring 模板

<?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="..." class="...">   
        <!-- collaborators and configuration for this bean go here -->
    </bean>

    <bean id="..." class="...">
        <!-- collaborators and configuration for this bean go here -->
    </bean>

    <!-- more bean definitions go here -->

</beans>

或者:
在这里插入图片描述

使用注解配置spring 模板

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

    <context:annotation-config/>
    
    <context:component-scan base-package="com"></context:component-scan>

</beans>

spring-test

在这里插入图片描述
在这里插入图片描述

原文链接:https://blog.csdn.net/weixin_43270493/article/details/85057140
原文链接:https://blog.csdn.net/qq_42345446/article/details/92427372
原文链接:https://blog.csdn.net/qq_42345446/article/details/93379525

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值