IOC容器,IOC操作bean管理

4 篇文章 0 订阅

目录

三 IOC容器

3.1 IOC容器概述

什么是IOC: 是一个中间容器,即“控制反转”,不是什么技术,而是一种设计思想Ioc意味着将你设计好的对象交给容器控制,而不是传统的在你的对象内部直接控制
如何理解好Ioc呢?理解好Ioc的关键是要明确“谁控制谁,控制什么,为何是反转(有反转就应该有正转了),哪些方面反转了”,那我们来深入分析一下:

谁控制谁,控制什么:传统Java SE程序设计,我们直接在对象内部通过new进行创建对象,是程序主动去创建依赖对象;而IoC是有专门一个容器来创建这些对象,即由Ioc容器来控制对 象的创建;谁控制谁?当然是IoC 容器控制了对象;控制什么?那就是主要控制了外部资源获取(不只是对象包括比如文件等)。
为何是反转,哪些方面反转了:有反转就有正转,传统应用程序是由我们自己在对象中主动控制去直接获取依赖对象,也就是正转;而反转则是由容器来帮忙创建及注入依赖对象;为何是反转?因为由容器帮我们查找及注入依赖对象,对象只是被动的接受依赖对象,所以是反转;哪些方面反转了?依赖对象的获取被反转了。

IOC三个核心:

  • XML解析
  • 工厂模式
  • 反射-----康师傅王振国

IOC接口:提供IOC容器实现的两种方式

ApplicationContext是BeanFactory的子接口,一般由开发人员使用,加载配置文件时就会创建对象
BeanFactory是Spring内部使用的接口,不建议开发人员使用,加载配置文件时不会创建对象,再获取对象时才会创建

3.2 IOC Bean管理操作


在spring xml 配置文件中,使用bean标签,标签里添加对应的属性,就可以实现对象的创建,创建对象时,也是默认执行无参构造方法完成对象创建。

3.2.1bean标签的常用属性:
id:是bean的唯一标识,相当于起别名;
class:指定bean的具体实现类,使用类的全限定名(包类路径);
property:< bean >的子元素,用于调用bean实例中的setter方法完成属性赋值,从而完成依赖注入。该元素的name属性指定bean实例中的属性名,ref属性或value属性用于指定参数值;
constructor-arg:< bean >元素的子元素,用于构造器实例化时完成依赖注入;

3.2.2属性值的两种方式

正常赋属性值(正转)

package com.pan.spring5;

public class User {
   private String uName;

    public void setuName(String uName) {
        this.uName = uName;
    }

    public static void main(String[] args) {
        User user = new User();
        user.setuName("张胜志");
    }
}

通过IOC容器调用属性值

公共方法类

package com.pan.spring5;

public class User {
   private String uName;
   private int age;

    public void setAge(int age) {
        this.age = age;
    }

    public void setuName(String uName) {
        this.uName = uName;
    }

   public void teatDemo(){
       System.out.println(uName+"......"+age);
   }
}

XML配置文件,赋属性值,并创建好公共方法的对象

<bean id="user" class="com.pan.spring5.User">
   <property name="uName" value="潘胜志"></property>
   <property name="age" value="20"></property>
</bean>

调用IOC容器类

package com.pan.spring5.testdemo;

import com.pan.spring5.User;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class TestSpring5 {
    @Test
    public void testAdd(){
        // 1.加载spring配置文件

        ApplicationContext context =
                new ClassPathXmlApplicationContext("bean1.xml");
        //2.获取配置创建的对象,这里就不需要new 一个对象了可以直接获取
        User user = context.getBean("user", User.class);

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

有参构造注入

package com.pan.spring5;

public class Orders {

    private String oname;
    private String address;

    //有参构造
    public Orders(String oname,String address) {
        this.address=address;
        this.oname=oname;
    }
    public void testDemo2(){
        System.out.println(address+":::::"+oname);
    }
}

xml:有参构造注入constructor-arg name value.

<bean id="orders" class="com.pan.spring5.Orders">
   <constructor-arg name="oname" value="abc"></constructor-arg>
   <constructor-arg name="address" value="china"></constructor-arg>
</bean>

P名称空间注入

作用简化了注入属性

给p标签一个空间,既可以直接到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"
       <!-- 给予一个p标签的空间 -->
       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="user" class="com.pan.spring5.User" p:uanme = "张万森" ,P:age = "20"> </bean>
3.2.3 Ioc注入其他类型属性

空值设置

<bean id="user" class="com.pan.spring5.User">
   <property name="age"><null/></property>
   <property name="uName" value="潘胜志"></property>
<!--   <property name="age" value="20"></property>-->
</bean>

属性值中包含特殊符号,要么转义要么使用将内容写到CDATA

<property name="age">
   <value>
      <![CDATA[<<19>>]]>
   </value>
</property>
3.2.4 在配置文件中注入其他对象 ref = " 配置里创建的对象"(注入内部bean)
<bean>
	<property name = "dept" ref = "dept"></property>
</bean>

<bean id = "dept" class = "com.pan.spring5.bean.Dept">
    <property name = "dname" value = "财务部"></property>
</bean>

ref 将另外一个bean 创建的对象引入同一个bean里

作用:当测试类调用时,会将其他类的属性一并合并运行

3.2.5 级联赋值

第一种:在内部bean注入属性

<bean id = "emp" class = "com.pam.spring5.Emp">
    <property name = "ename" value = "lucy"></property>
    <property name = "gender" value = ""></property>
    <!-- 级联赋值 -->
    <property name = "dept" ref = "dept"></property>
    <!--在内部注入属性-->
    <property name = "dept.dname" value = "技术部"></property>
</bean>

<bean id = "dept" class = "com.pan.spring5.bean.Dept"></bean>

第二种方法:在外部注入bean属性

<bean id = "dept" class = "com.pan.spring5.bean.Dept">
    <property name = "dname" value = "财务部"></property>
</bean>
3.2.6属性注入(map,list,数组)
package com.lc.collection;
 
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
 
public class Department {
 
	private String name;
	private String [] empName;//数组
	private List<Employee> empList;//list集合
	private Set<Employee> empsets;//set集合
	private Map<String,Employee> empMaps;//map集合
	private Properties pp;//Properties的使用
 
	
	public Set<Employee> getEmpsets() {
		return empsets;
	}
	public void setEmpsets(Set<Employee> empsets) {
		this.empsets = empsets;
	}
	public String[] getEmpName() {
		return empName;
	}
	public void setEmpName(String[] empName) {
		this.empName = empName;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public List<Employee> getEmpList() {
		return empList;
	}
	public void setEmpList(List<Employee> empList) {
		this.empList = empList;
	}
	public Map<String, Employee> getEmpMaps() {
		return empMaps;
	}
	public void setEmpMaps(Map<String, Employee> empMaps) {
		this.empMaps = empMaps;
	}
	public Properties getPp() {
		return pp;
	}
	public void setPp(Properties pp) {
		this.pp = pp;
	}
 
}

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:context="http://www.springframework.org/schema/context"
		xmlns:tx="http://www.springframework.org/schema/tx"
		xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
				http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd
				http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd">
 
<bean id="department" class="com.hsp.collection.Department">
<property name="name" value="财务部"/>
 
<!-- 给数组注入值 -->
<property name="empName">
	<list>
		<value>小明</value>
		<value>小明小明</value>
		<value>小明小明小明小明</value>
	</list>
</property>
 
<!-- 给list注入值 list 中可以有相当的对象 -->
<property name="empList">
	<list>
		<ref bean="emp2" />
		<ref bean="emp1"/>
		<ref bean="emp1"/>
		<ref bean="emp1"/>
		<ref bean="emp1"/>
		<ref bean="emp1"/>
		<ref bean="emp1"/>
	</list>
</property>
 
<!-- 给set注入值 set不能有相同的对象 -->
<property name="empsets">
	<set>
		<ref bean="emp1" />
		<ref bean="emp2"/>
		<ref bean="emp2"/>
		<ref bean="emp2"/>
		<ref bean="emp2"/>
	</set>
</property>
 
<!-- 给map注入值 map只有key不一样,就可以装配value -->
<property name="empMaps">
	<map>
		<entry key="11" value-ref="emp1" /> 
		<entry key="22" value-ref="emp2"/>
		<entry key="22" value-ref="emp1"/>
	</map>
</property>
 
<!-- 给属性集合配置 -->
<property name="pp">
	<props>
		<prop key="pp1">abcd</prop>
		<prop key="pp2">hello</prop>
	</props>
</property>
</bean>
 
<bean id="emp1" class="com.hsp.collection.Employee">
	<property name="name" value="北京"/>
	<property name="id" value="1"/>
</bean>
<bean id="emp2" class="com.hsp.collection.Employee">
	<property name="name" value="天津"/>
	<property name="id" value="2"/>
</bean>
 
</beans>
3.2.7 bean的作用域

spring默认的bean是单实例对象

设置单多实例对象 - 属性 scope 实现

  1. scope 属性值
    • singleton , 表示单实例对象
    • protoptype ,多实例对象
    • request ,把这个值变成一个请求
    • session , 把这个之变成一个会话保存
3.2.8 bean 的生命周期
  1. 创建bean实例 ,通过构造器创建bean实例(无参构造)
  2. 为bean的属性设置和对其他bean的引用(调用set的方法)
  3. 调用bean的初始化方法(需要配置)
  4. bean获取(对象获取到了)
  5. 关闭容器,调用bean 的销毁方法(需要进行配置方法)

生命周期代码示例

创建方法类。

package com.pan.spring5.methodclass;

public class Orders {

    private String oname;
    private String address;

    //有参构造


    //无参构造
    public Orders(){
        System.out.println("第一步  默认执行了无参构造,创建了bean 的实例");
    }
    
    //设置属性值的方法
    public void setAddress(String address) {
        this.address = address;
        System.out.println("第二步 设置了oname 的属性值");
    }
    
	//设置属性值的方法
    public void setOname(String oname) {
        this.oname = oname;
        System.out.println("第三步 设置了address 的属性值");
    }

    //创建初始化方法
    public void initMethod(){
        System.out.println("第四步 执行了初始化方法");
    }

    //销毁方法
    public void destroyMethod(){
        System.out.println("第六步 销毁bean创建的实例");
    }

}

创建对象和执行方法的XML文件

  • init-method destroy-method
   <bean id="orders" class="com.pan.spring5.methodclass.Orders" init-method="initMethod" destroy-method="destroyMethod">
      <property name="oname" value="电脑"></property>
      <property name="address" value="电脑"></property>
   </bean>

调用测试类

@Test
public void testOrders(){
    ApplicationContext context =
            new ClassPathXmlApplicationContext("com/pan/spring5/beanpackage/bean2.xml");

    Orders orders = context.getBean("orders", Orders.class);
    System.out.println("第五步 获取创建bean的实例对象");
    System.out.println(orders);
    orders.testDemo2();

    //销毁bean,多态向下转型,调用close方法
    ((ClassPathXmlApplicationContext) context).close();
}
3.3.9 bean的后置处理器
  1. 创建bean实例 ,通过构造器创建bean实例(无参构造)
  2. 为bean的属性设置和对其他bean的引用(调用set的方法)
  3. 调用bean的后置处理器将实例传递给后置处理器
  4. 调用bean的初始化方法(需要配置)
  5. bean获取(对象获取到了)
  6. 关闭容器,调用bean 的销毁方法(需要进行配置方法)

创建后置处理器

  1. 创建类,实现接口BeanPostProcessor ,创建后置处理器

  2. //代码展示
    package com.pan.spring5;
    
    import org.springframework.beans.BeansException;
    import org.springframework.beans.factory.config.BeanPostProcessor;
    
    public class MyBean 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;
        }
    }
    
    
  3. <!-- 配置后置处理器 -->
    <bean id = "myBeanpost" class = "com.pan.spring5.methodclass.MyBean"></bean>
    

3.3.Bean自动装配

概念理解:自动装配指的是,根据指定装配规则(属性名称或属性类型),spring自动将匹配的属性值进行注入

演示代码

byName byType

引入外部文件

自动装配

注解配置

外部属性文件

直接配置数据库信息

  1. 配置德鲁伊连接池

    • 直接配置

      1. 引入德鲁伊jar包-----放入lib包中--------->在引入depedencey中 druid-1.1.5.jar

      2. 连接池配置

        <bean id = "datasource" class = "com.pan.spring5.DruidDataSource">
            <property name = "driverClaassName" value = "com.mysql.jdbc.Driver"></property>
            <property name = "url" value = "jdbc:mysql://localhost:3306/userDB"></property>
            <property name = "username" value = "root"></property>
            <property name = "password" value = "123456"></property>
        </bean>
        
    • 引入外部属性文件配置数据库连接池

      1. 床架你外部属性文件,property的配置信息

      2. prop.driverClass = com.pan.spring5.DruidDataSource
        prop.url = jdbc:mysql://localhost:3306/userDB
        prop.username = root
        prop.password = 123456
        

        配置文件

      3. xml 文件配置

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

        http://www.springframework.org/schema/beans/spring-context.xsd"

        <beans xmlns="http://www.springframework.org/schema/beans"
               xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
               <!-- 给予一个p标签的空间 -->
               xmlns:p="http://www.springframework.org/schema/p"
        	   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/beans/spring-context.xsd">
        
        <!-- 引入外部文件 -->
        <context:property-placeholder lacation = "classpath:jdbc.properties"/>
        
        <bean id = "datasource" class = "com.pan.spring5.DruidDataSource">
            <property name = "driverClaassName" value = "${prop.driverClass}"></property>
            <property name = "url" value = "${prop.url}"></property>
            <property name = "username" value = "${prop.username}"></property>
            <property name = "password" value = "${prop.password}"></property>
        </bean>
        

        ${} 用这个表达式引入外部文件属性值

3.4 IOC操作bean管理(基于注解方式)

1**.什么是注解**:注解是代码的特殊标记,格式:@注解名称(属性名称 = 属性值,属性名称 =属性值 …)

注解的使用:注解作用在类方面,方法上面,属性上面

使用注解的目的:简化xml配置

2.Spring针对Bean管理中创建对象提供的注解

  • @Component 泛指各种组件 以下几种都可称为 @Component
  • @Service 业务层
  • @Controller 控制层
  • @Respository 数据访问层

上面的注解都是一样的,都可以用来创建bean的实例

3.4.1基于注解方式实现对象创建
  1. 引入jar包 spring-aop-5.2.6.RELEASE.jar

  2. 开启组件扫描(开启注解支持)

    • 如果扫描多个包,多个包使用逗号隔开

    • 或者扫描包的上层目录

      <context-component-scan base-package = "com.pan"></context-component-scan>
      

​ 3.创建类,在类上面添加创建对象注解

  • 在注解里value的值可以省略

  • 默认值是类名称,首字母都会转成小写

    <!-- use-default-filters = "false"  将过滤器改为自行配置 -->
    <!-- context:include-filter  设置扫描内容 -->
    <context-component-scan base-package = "com.pan" use-default-filters = "false">
    	<context:include-filter type = "annotation"
                                experssion = "com.pam.Controller"/>
    </context-component-scan>
    
3.4.2 基于注解方式实现属性的注入
  1. @Autowired:根据属性类型自动装配
    • 首先了IOC操作bean管理 ,bean管理是指创建对象,注入属性。当我们将一个类上标注@Service ,@Cotroller ,@Component ,等待注解后,spring的组件扫描自动发现他 并将其初始化为spring应用上下文的bean .
    • 当这个类被使用时,加了注解 @autowriter 时 ,会自动创建bean,以致使用。
    • 作用 :可以标注在属性上,方法上,和构造器上,来完成自动装,根据属性值类型来判断。
    • 使用:它可以标注在属性上,方法和构造器上,那它们有何区别呢,简单来说是他们的初始化顺序不同,推荐对构造器上使用,如果在接口上使用,其注入的是接口的实现类,实现类很多这时就需要根据属性名称来找到这个bean
  2. @Qualifier:根据属性名称进行注入 ==========依据其上便都可以解释
  3. @Resource:可以根据类型注入,可以根据名称注入
  4. @Value:注入普通类型属性
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值