Spring5 中的 IOC

Spring5—IOC

一,IOC是基于容器完成,IOC容器底层就是对象工厂。

二,IOC容器实现两种方式:

  1. BeanFactory
    Spring内部使用,开发人员一般不使用
    特点:加载配置文件不会去创建对象,在获取或使用对象的时候才会创建
		//1 加载spring配置文件,不创建对象
        BeanFactory context =
                new ClassPathXmlApplicationContext("bean1.xml");

        //2 获取配置创建的对象,创建对象
        User user = context.getBean("user", User.class);
  1. ApplicationContext
    BeanFactory的子接口,提供更多更强大的功能,一般开发人员使用
    特点:加载配置文件就会去创建对象
        //1 加载spring配置文件,创建对象
        ApplicationContext context =
                new ClassPathXmlApplicationContext("bean1.xml");

        //2 获取配置创建的对象
        User user = context.getBean("user", User.class);

三,ApplicationContext实现类

  • FileSystemXmlApplicationContext
    文件位置在盘里面(如C盘,D盘。。。)
  • ClassPathXmlApplicationContext
    文件位置在类里面

四,IOC操作Bean管理

  • 两个操作: 创建对象, 注入属性

  • 两个实现方式:基于xml,基于注解

基于XML

1,基于XML

一. xml创建对象

	<!--1,配置User对象创建-->
    <bean id="user" class="com.at.spring5.User"></bean>
- 使用bean标签
- bean标签常用属性:

	(1)id :位移标识
	(2)class :类全路径
	(3) name : 和 id 类似,区别 id 不能加特殊符号, name 可以加特殊符号

 - 用xml创建对象时,默认使用无参数构造方法
  1. xml注入属性
    (1)DI:依赖注入,就是注入属性

    通常:

public class Book {
    private String bname;

    //1.set方法注入
    public void setBname(String bname) {
        this.bname = bname;
    }

    public static void main(String[] args) {
        Book book = new Book();
        book.setBname("abc");
    }
}
public class Book {
    private String bname;

    //2.有参数构造注入
    public Book(String bname) {
        this.bname = bname;
    }

    public static void main(String[] args) {
        Book book = new Book("abc");
    }
}

在Spring中:

  1. set注入
    (1)创建类,定义属性和对应set方法
//set方法注入
public class Book {
    //创建属性
    private String bname;
    private String bauthor;

    //创建属性对应的set方法
    public void setBname(String bname) {
        this.bname = bname;
    }

    public void setBauthor(String bauthor) {
        this.bauthor = bauthor;
    }
}

(2)在spring配置文件配置对象创建,配置属性注入

<!--2,set方法注入属性-->
    <bean id="book" class="com.at.spring5.Book">
        <!--使用property完成属性注入
            name: 类里面属性名称
            value: 向属性注入的值
        -->
        <property name="bname" value="三国演义"></property>
        <property name="bauthor" value="罗贯中"></property>
    </bean>

(3)测试

		//1 加载spring配置文件
        ApplicationContext context =
                new ClassPathXmlApplicationContext("bean1.xml");

        //2 获取配置创建的对象
        Book book = context.getBean("book", Book.class);

        System.out.println(book);
        book.testDemo();

其中testDemo()为:

    public void testDemo() {
        System.out.println(bname + " & " + bauthor);
    }

结果为:

com.at.spring5.Book@c81cdd1
三国演义 & 罗贯中

二. 有参数的注入
(1) 创建一个类,定义属性,创建属性对应有参数构造方法

//有参数构造注入
public class Orders {
    //属性
    private String oname;
    private String address;

    //有参数构造
    public Orders(String oname, String address) {
        this.oname = oname;
        this.address = address;
    }
}

(2)在spring配置文件中

    <!--3 有参数构造注入属性-->
    <bean id="orders" class="com.at.spring5.Orders">
        <constructor-arg name="oname" value=""></constructor-arg>
        <constructor-arg name="address" value="西安"></constructor-arg>
    </bean>

(3)测试

		//1 加载spring配置文件
        ApplicationContext context =
                new ClassPathXmlApplicationContext("bean1.xml");

        //2 获取配置创建的对象
        Orders orders = context.getBean("orders", Orders.class);

        System.out.println(orders);
        orders.testOrders();

其中testOrders()为:

    public void testOrders() {
        System.out.println(oname + " & " + address);
    }

结果

com.at.spring5.Orders@42607a4f
车 & 西安

同样的,配置文件中也可以用 index,其中 0 表示调用对象的第一个参数,如本例中时 oname,但一般习惯用 name ,更加准确。

<constructor-arg index="0" value=""></constructor-arg>

三. set注入的简化 , p名称空间注入
使用p名称空间输入,基于xml配置

1. 添加p名称空间在配置文件中
xmlns:p="http://www.springframework.org/schema/p"
2.进行属性注入
<bean id="book" class="com.at.spring5.Book" p:bname="西游记" p:bauthor="吴承恩"></bean>
3.结果
com.at.spring5.Book@12c8a2c0
西游记 & 吴承恩

四. 其他注入方式
(1)字面量

  • null值
    xml中:
    <!--2,set方法注入属性-->
    <bean id="book" class="com.at.spring5.Book">
        <!--使用property完成属性注入
            name: 类里面属性名称
            value: 向属性注入的值
        -->
        <property name="bname" value="三国演义"></property>
        <!--null值-->
        <property name="bauthor">
            <null></null>
        </property>
    </bean>

结果:

com.at.spring5.Book@c81cdd1
三国演义 & null

  • 属性包含特殊符号

    1,把<>进行转义 ‘&lt’ ; ‘&gt’ ;
    2,把特殊符号内容写道CDATA

    <bean id="book" class="com.at.spring5.Book">
        <!--使用property完成属性注入
            name: 类里面属性名称
            value: 向属性注入的值
        -->
        <property name="bname" value="三国演义"></property>

        <!--属性值包含特殊符号
            1,把<>进行转义 &lt; &gt;
            2,把特殊符号内容写道CDATA
        -->
        <property name="bauthor">
            <value>
                <![CDATA[<<测试>>]]>
            </value>
        </property>
    </bean>

结果:

com.at.spring5.Book@c81cdd1
三国演义 &
<<测试>>

另外:

    <bean id="book" class="com.at.spring5.Book">
        <!--使用property完成属性注入
            name: 类里面属性名称
            value: 向属性注入的值
        -->
        <property name="bname" value="三国演义"></property>

        <!--属性值包含特殊符号
            1,把<>进行转义 &lt; &gt;
            2,把特殊符号内容写道CDATA
        -->
        <property name="bauthor">
            <value><![CDATA[<<测试>>]]></value>
        </property>
    </bean>

结果:

com.at.spring5.Book@c81cdd1
三国演义 & <<测试>>

(2)注入属性-外部 bean

  • 创建两个类 service 和 dao 类
public class UserService {

    //创建UserDao类型属性,生成set方法
    private UserDao userDao;

    public void setUserDao(UserDao userDao) {
        this.userDao = userDao;
    }

    public void add() {
        System.out.println("serviceadd--");
        userDao.update();
    }
}
public interface UserDao {
    public  void update();
}

public class UserDaoImpl implements UserDao {
    @Override
    public void update() {
        System.out.println("daoupdate--");
    }
}
  • 在 service 调用 dao 里面的方法
  • 在spring配置文件中进行配置
    <!--1, service 和 dao 对象创建-->
    <bean id="userService" class="com.at.spring5.service.UserService">
        <!--注入userDao对象
            name属性值: 类里面属性名称
            ref属性: 创建 userDao 对象 bean 标签 id 值
        -->
        <property name="userDao" ref="userDaoImpl"></property>
    </bean>
    <bean id="userDaoImpl" class="com.at.spring5.dao.UserDaoImpl"></bean>

测试:

    public void testAdd() {
        //1, 加载 spring 配置文件
        ApplicationContext context =
                new ClassPathXmlApplicationContext("bean2.xml");

        //2, 获取配置创建的对象
        UserService userService = context.getBean("userService", UserService.class);

        userService.add();
    }

结果:

serviceadd–
daoupdate–

(3)注入属性-内部 bean 和级联赋值

  • 一对多关系:(举例)部门和员工,部门为一,员工为多
  • 在实体类之间表示一对多的关系,员工表示所属部门,使用对象类型属性进行表示
//部门类
public class Dept {
    private String dname;   //部门名

    public void setDname(String dname) {
        this.dname = dname;
    }

    @Override
    public String toString() {
        return "Dept{" +
                "dname='" + dname + '\'' +
                '}';
    }
}
//员工类
public class Emp {
    private String ename;   //姓名
    private String gender;  //性别
    //员工属于某个部门,使用对象形式表示
    private Dept dept;

    public void setEname(String ename) {
        this.ename = ename;
    }

    public void setGender(String gender) {
        this.gender = gender;
    }

    public void setDept(Dept dept) {
        this.dept = dept;
    }

    public void add() {
        System.out.println(ename + " | " + gender + " | " + dept);
    }
}
  • 在spring中进行配置
    <!--内部 bean-->
    <bean id="emp" class="com.at.spring5.bean.Emp">
        <!--先设置前两个String类型属性-->
        <property name="ename" value="张三"></property>
        <property name="gender" value=""></property>
        <!--设置第三个对象类型的属性-->
        <property name="dept">
            <bean id="dept" class="com.at.spring5.bean.Dept">
                <property name="dname" value="保安部"></property>
            </bean>
        </property>
    </bean>

常习惯用外部bean

  • 测试
    public void testAdd1() {
        //1, 加载 spring 配置文件
        ApplicationContext context =
                new ClassPathXmlApplicationContext("bean3.xml");

        //2, 获取配置创建的对象
        Emp emp = context.getBean("emp", Emp.class);

        emp.add();
    }
  • 结果

张三 | 男 | Dept{dname=‘保安部’}

(4)注入属性 – 级联赋值

  • 方法一:
    <!--级联赋值-->
    <bean id="emp" class="com.atguigu.spring5.bean.Emp">
        <!--先设置前两个String类型属性-->
        <property name="ename" value="张三"></property>
        <property name="gender" value=""></property>
        <!--级联赋值-->
        <property name="dept" ref="dept"></property>
    </bean>
    <bean id="dept" class="com.atguigu.spring5.bean.Dept">
        <property name="dname" value="财务部"></property>
    </bean>

测试结果

张三 | 男 | Dept{dname=‘财务部’}

  • 方法二:
    //先在Emp.class中生成dept的get方法
    public Dept getDept() {
        return dept;
    }
    <!--级联赋值-->
    <bean id="emp" class="com.atguigu.spring5.bean.Emp">
        <!--先设置前两个String类型属性-->
        <property name="ename" value="张三"></property>
        <property name="gender" value=""></property>
        <!--级联赋值-->
        <property name="dept" ref="dept"></property>
        <property name="dept.dname" value="技术部"></property>
    </bean>
    <bean id="dept" class="com.atguigu.spring5.bean.Dept"></bean>

测试结果

张三 | 男 | Dept{dname=‘技术部’}

(5) 集合类型属性注入

  • 注入数组类型属性
  • 注入List集合类型属性
  • 注入Map集合

创建类定义Stu类的属性:

public class Stu {
    //1, 数组类型属性
    private String[] courses;

    //2, list集合类型属性
    private List<String> list;

    //3, map集合类型属性
    private Map<String, String> maps;

    //4, set集合类型属性
    private Set<String> sets;

    public void setCourses(String[] courses) {
        this.courses = courses;
    }

    public void setList(List<String> list) {
        this.list = list;
    }

    public void setMaps(Map<String, String> maps) {
        this.maps = maps;
    }

    public void setSets(Set<String> sets) {
        this.sets = sets;
    }
}

spring:

    <!--1, 集合类型属性注入-->
    <bean id="stu" class="com.at.spring5.collectiontype.Stu">
        <!--数组类型属性注入-->
        <property name="courses">
            <array>
                <value>计算机导论</value>
                <value>操作系统</value>
            </array>
        </property>
        <!--list类型属性注入-->
        <property name="list">
            <list>
                <value>张三</value>
                <value>李四</value>
            </list>
        </property>
        <!--map类型属性注入-->
        <property name="maps">
            <map>
                <entry key="JAVA" value="java"></entry>
                <entry key="PYTHON" value="python"></entry>
            </map>
        </property>
        <!--set类型属性注入-->
        <property name="sets">
            <set>
                <value>MySql</value>
                <value>Linux</value>
            </set>
        </property>
    </bean>

测试:
在Stu中加上

    public void test(){
        System.out.println(Arrays.toString(courses));
        System.out.println(list);
        System.out.println(maps);
        System.out.println(sets);
    }

测试类

public class testDemo1 {
    @Test
    public void testCollection() {
        ApplicationContext context =
                new ClassPathXmlApplicationContext("bean1.xml");
        Stu stu = context.getBean("stu", Stu.class);
        stu.test();
    }
}

结果:

[计算机导论, 操作系统]
[张三, 李四]
{JAVA=java, PYTHON=python}
[MySql, Linux]

  • 在集合里面设置对象类型值
    创建Course类
//课程类
public class Course {
    private String cname;

    public void setCname(String cname) {
        this.cname = cname;
    }
    
    @Override
    public String toString() {
        return "Course{" +
                "cname='" + cname + '\'' +
                '}';
    }
}

在Stu中添加:

    //学生所学多门课程
    private List<Course> courseList;

    public void setCourseList(List<Course> courseList) {
        this.courseList = courseList;
    }

在Stu的test方法中添加:

System.out.println(courseList);

在spring配置文件中添加
bean中:

        <!--注入list集合类型, 值是对象-->
        <property name="courseList">
            <list>
                <ref bean="coursel1"></ref>
                <ref bean="coursel2"></ref>
            </list>
        </property>

beans中:

    <!--创建多个course对象-->
    <bean id="coursel1" class="com.at.spring5.collectiontype.Course">
        <property name="cname" value="Java Spring课程"></property>
    </bean>
    <bean id="coursel2" class="com.at.spring5.collectiontype.Course">
        <property name="cname" value="MySql课程"></property>
    </bean>

结果:

[计算机导论, 操作系统]
[张三, 李四]
{JAVA=java, PYTHON=python}
[MySql, Linux]
[Course{cname=‘Java Spring课程’}, Course{cname=‘MySql课程’}]

(其中新加的是最后一行)

  • 把集合注入部分提取出来
    (1)在spring配置文件中引入名称空间 util
<?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"
       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
                           http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-beans.xsd">

</beans>

(2)使用util标签完成list集合注入提取

    <!--1, 提取list集合类型属性注入-->
    <util:list id="bookList">
        <!-- 对象类型时用ref-->
        <value>计算机导论</value>
        <value>Java入门到放弃</value>
        <value>MySql从从建库到跑路</value>
    </util:list>

    <!--2, 提取list集合类型属性注入使用-->
    <bean id="book" class="com.at.spring5.collectiontype.Book">
        <property name="list" ref="bookList"></property>
    </bean>

(优势是其他 bean 可以直接利用 bookList 不需要再重写 bookList)
测试结果:

[计算机导论, Java入门到放弃, MySql从从建库到跑路]

五,IOC 操作 Bean 管理(FactoryBean)
(和 BeanFactory 不一样)

  1. Spring 中有两种 bean:普通 bean工厂 bean(FactoryBean)
  2. 普通 bean:在配置文件中定义bean类型就是返回类型
  3. 工厂bean:在配置文件定义bean类型可以与返回类型不一样
    第一步,创建类,让这个类作为工厂 bean ,实现接口 FactoryBean
    第二步,实现接口里面的方法,在实现的方法中定义返回的 bean 类型
public class MyBean implements FactoryBean<Course> {

    //定义返回bean
    @Override
    public Course getObject() throws Exception {
        Course course = new Course();
        course.setCname("abc");
        return course;
    }

    @Override
    public Class<?> getObjectType() {
        return null;
    }

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

public class testDemo1 {
    @Test
    public void testCollection() {
        ApplicationContext context =
                new ClassPathXmlApplicationContext("bean2.xml");
        Course course = context.getBean("myBean", Course.class);
        System.out.println(course);
    }
}
<?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"
       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
                           http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd">
    <bean id="myBean" class="com.at.spring5.factorybean.MyBean"></bean>
</beans>

结果:

Course{cname=‘abc’}

六,IOC 操作 Bean 管理(Bean 作用域)

  1. 在 Spring 里,设置创建 bean 实例是单实例还是多实例
  2. 在 Spring 里,默认情况下,bean 是单实例对象
    查看单实例:
    @Test
    public void testCollection() {
        ApplicationContext context =
                new ClassPathXmlApplicationContext("bean1.xml");
        Book book1 = context.getBean("book", Book.class);
        Book book2 = context.getBean("book", Book.class);
        System.out.println(book1);
        System.out.println(book2);
    }

结果:

com.at.spring5.collectiontype.Book@71623278
com.at.spring5.collectiontype.Book@71623278

3.如何设置单实例还是多实例
(1)在 spring 配置文件 bean 标签里面有属性(scope)用于设置单实例还是多实例
(2)scope 属性值
第一个值 默认值,singleton,表示是单实例对象
第二个值 prototype,表示是多实例对象
多实例:

    <!--2, 提取list集合类型属性注入使用-->
    <bean id="book" class="com.at.spring5.collectiontype.Book" scope="prototype">
        <property name="list" ref="bookList"></property>
    </bean>

结果:

com.at.spring5.collectiontype.Book@16022d9d
com.at.spring5.collectiontype.Book@7e9a5fbe

(3)singleton 和 prototype 区别
第一 singleton 单实例,prototype 多实例
第二 设置 scope 值是 singleton 时候,加载 spring 配置文件时候就会创建单实例对象;设置 scope 值是prototype 时候,不是在加载 spring 配置文件时候创建对象,在调用 getBean 方法时候才创建多实例对象

其他:request,session

七,Bean生命周期

  1. 生命周期
    (1)从对象创建到对象销毁的过程为生命周期
  2. bean生命周期
    (1)通过构造器创建 bean 实例(无参数构造)
    (2)为 bean 的属性设置值和对其他 bean 引用(调用 set 方法)
    (3)调用 bean 的初始化的方法(需要进行配置初始化的方法)
    (4)bean 可以使用(对象获取到了)
    (5)当容器关闭时候,调用 bean 的销毁的方法(需要进行配置销毁的方法)
  3. bean 生命周期演示
    创建Orders对象:
public class Orders {
    //无参数构造

    public Orders() {
        System.out.println("第一步, 通过构造器创建 bean 实例(无参数构造)");
    }

    private String oname;

    public void setOname(String oname) {
        this.oname = oname;
        System.out.println("第二步, 为 bean 的属性设置值和对其他 bean 引用(调用 set 方法)");
    }

    //创建执行的初始化方法
    public void initMethod() {  //名字随便取
        System.out.println("第三步, 调用 bean 的初始化的方法(需要进行配置)");
    }

    //创建执行的销毁的方法
    public void destroyMethod() {  //名字随便取
        System.out.println("第五步, 执行销毁的方法");
    }
}

配置spring文件:

    <!--(第三步里) init-method=" "  调用初始化方法-->
    <!--(第五步里) destroy-method=" "  调用销毁方法-->
    <bean id="orders" class="com.at.spring5.bean.Orders" init-method="initMethod" destroy-method="destroyMethod">
        <property name="oname" value="手机"></property>
    </bean>

测试类:

    @Test
    public void testCollection() {
        ApplicationContext context =
                new ClassPathXmlApplicationContext("bean3.xml");
        Orders orders = context.getBean("orders", Orders.class);
        System.out.println("第四步, bean 可以使用(对象获取到了)");
        System.out.println(orders);

        //手动让 bean 实例销毁
        ((ClassPathXmlApplicationContext)context).close();
        //ApplicationContext强转ClassPathXmlApplicationContext,原因是ApplicationContext里没有close()方法
    }

结果:

第一步, 通过构造器创建 bean 实例(无参数构造)
第二步, 为 bean 的属性设置值和对其他 bean 引用(调用 set 方法)
第三步, 调用 bean 的初始化的方法(需要进行配置)
第四步, bean 可以使用(对象获取到了)
com.at.spring5.bean.Orders@78ac1102
第五步, 执行销毁的方法

  1. bean 的后置处理器,bean 生命周期有七步
    (1)通过构造器创建 bean 实例(无参数构造)
    (2)为 bean 的属性设置值和对其他 bean 引用(调用 set 方法)
    (3)把 bean 实例传递给 bean 后置处理器的方法(postProcessBeforeInitialization)
    (4)调用 bean 的初始化的方法(需要进行配置初始化的方法)
    (5)把 bean 实例传递给 bean 后置处理器的方法(postProcessAfterInitialization)
    (6)bean 可以使用(对象获取到了)
    (7)当容器关闭时候,调用 bean 的销毁的方法(需要进行配置销毁的方法)
  2. 演示添加后置处理器效果
    (1)创建类,实现接口 BeanPostProcessor,创建后置处理器
public class MyBeanPost 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;
    }
}

(2)配置spring文件

    <!--配置后置处理器, 它将会为spring配置文件中的所有bean都添加后置处理器-->
    <bean id="myBeanPost" class="com.at.spring5.bean.MyBeanPost"></bean>

(3)结果:

第一步, 通过构造器创建 bean 实例(无参数构造)
第二步, 为 bean 的属性设置值和对其他 bean 引用(调用 set 方法)
在初始化之前执行的方法
第三步, 调用 bean 的初始化的方法(需要进行配置)
在初始化之后执行的方法
第四步, bean 可以使用(对象获取到了)
com.at.spring5.bean.Orders@22eeefeb
第五步, 执行销毁的方法

八,Bean 管理,xml 自动装配

  1. 什么是自动装配
    (1)根据指定装配规则(属性名或者属性类型),spring 自动将匹配的属性值进行注入

  2. 演示自动装配过程

public class Dept {
    @Override
    public String toString() {
        return "Dept{}";
    }
}
public class Emp {
    private Dept dept;

    public void setDept(Dept dept) {
        this.dept = dept;
    }

    @Override
    public String toString() {
        return "Emp{" +
                "dept=" + dept +
                '}';
    }

    public void test() {
        System.out.println(dept);
    }
}

(1)根据属性名称自动注入

    <!--实现自动装配
        bean标签属性autowire,配置自动装配
        autowire属性常用两个值:
           byName根据属性名称注入 (注入值bean的id值和类属性名称一样
           byType根据属性类型注入
    -->
    <bean id="emp" class="com.at.spring5.autowire.Emp" autowire="byName">
            <!--<property name="dept" ref="dept"></property>-->
    </bean>
    <bean id="dept" class="com.at.spring5.autowire.Dept"></bean>

(2)根据属性类型自动注入

    <!--实现自动装配
        bean标签属性autowire,配置自动装配
        autowire属性常用两个值:
           byName根据属性名称注入 (注入值bean的id值和类属性名称一样
           byType根据属性类型注入
    -->
    <bean id="emp" class="com.at.spring5.autowire.Emp" autowire="byType">
            <!--<property name="dept" ref="dept"></property>-->
    </bean>
    <bean id="dept" class="com.at.spring5.autowire.Dept"></bean>

九,Bean管理外部属性文件
1,直接配置数据库信息
(1)配置德鲁伊连接池
(2)引入德鲁伊连接池依赖的 jar 包

    <!--直接配置连接池-->
    <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
        <property name="driverClassName" 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>

2,引入外部属性文件配置数据库连接池
(1)创建外部属性文件,properties 格式文件,写数据库信息
创建了一个jdbc.properties文件

stu.driverClass=com.mysql.jdbc.Driver
stu.url=jdbc:mysql://localhost:3306/demo1?useUnicode=true&characterEncoding=utf-8
stu.userName=root
stu.password=123456

(2)把外部 properties 属性文件引入到 spring 配置文件中
引入 context 名称空间

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

在 spring 配置文件使用标签引入外部属性文件

    <!--引入外部的属性文件-->
    <context:property-placeholder location="classpath:jdbc.properties"/>

    <!--直接配置连接池-->
        <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
            <property name="driverClassName" value="${stu.driverClass}"></property>
            <property name="url" value="${stu.url}"></property>
            <property name="username" value="${stu.userName}"></property>
            <property name="password" value="${stu.password}"></property>
        </bean>

基于注解

IOC操作 Bean 管理,基于注解方式
一,什么是注解
(1)注解是代码特殊标记,格式;@注解名称(属性名称 = 属性值,属性名称 = 属性值)
(2)使用注解,注释可作用在类上面,方法上面,属性上面
(3)使用注解的目的:简化xml配置

二,Spring 针对 Bean 管理中创建对象提供注解
(1)@Component :普通组件,都可以创建对象
(2)@Service :一般在业务逻辑层
(3)@Controller :一般在web层上
(4)@Repository :一般持久层上
上面四个注解功能是一样的,都可以用来创建 bean 实例

三,基于注解方式实现对象创建
第一步,引入依赖包jar:spring-aop-5.2.6.RELEASE
第二步,开启组件扫描

<!--开启组件扫描
        1, 如果扫描多个包,多个包使用逗号隔开  "com.at.spring5.dao,com.at.spring5.service"
        2, 扫描包上层目录  "com.at"
    -->
    <context:component-scan base-package="com.at"></context:component-scan>

第三步,随便创建类,在类上面添加创建对象注释,UserService类

//在注解里面value属性值可以省略不写,默认值是类名称,首字母小写
//UserService -- userService
//其他几种注解方式都可以,这里举例 @Component
@Component(value = "userService") //<bean id="userService" class=".."/>
public class UserService {
    public void add() {
        System.out.println("UserService add-------");
    }
}

测试:

public class TestSpring5Demo3 {
    @Test
    public void testService() {
        ApplicationContext context =
                new ClassPathXmlApplicationContext("bean1.xml");
        UserService userService = context.getBean("userService", UserService.class);
        System.out.println(userService);
        userService.add();
    }
}

结果

com.at.spring5.service.UserService@11dc3715
UserService add-------

四,开启组件扫描配置

    <!--例1
        use-default-filters="false" 表示现在不使用默认 filter (不扫描所有) , 自己配置 filter
        context:include-filter , 扫描哪些内容
        本例只扫描 com.at 下的注释为 Controller 的包
    -->
    <context:component-scan base-package="com.at" use-default-filters="false">
        <context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
    </context:component-scan>
    <!--例2
        下面配置扫描所有内容
        context:exclude-filter , 设置哪些内容不扫描
    -->
    <context:component-scan base-package="com.at">
        <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
    </context:component-scan>

五,基于注解方式实现属性注入
(1) @Autowired : 根据属性类进行自动装配
第一步,把 service 和 dao 对象创建,在 service 和 dao 类添加创建对象注解

    <context:component-scan base-package="com.at"></context:component-scan>
public interface UserDao {
    public void add();
}

@Resource
public class UserDaoImpl implements UserDao{
    @Override
    public void add() {
        System.out.println("UserDao add-----");
    }
}

第二步,在 service 注入 dao 对象,在 service 类添加 dao 类属性,在属性上面使用注解

@Service
public class UserService {

    //定义dao类型属性
    //不需要添加set方法
    //添加注入属性注解
    @Autowired
    private UserDao userDao;

    public void add() {
        System.out.println("UserService add-------");
        userDao.add();
    }
}

结果:

com.at.spring5.service.UserService@5bfa9431
UserService add-------
UserDao add-----

(2) @Qualifier : 根据属性名称进行注入
它要和 @Autowired 一起使用。

@Service
public class UserService {

    //定义dao类型属性
    //不需要添加set方法
    //添加注入属性注解
    @Autowired
    @Qualifier(value = "userDaoImpl1") //根据名称注入
    private UserDao userDao;

    public void add() {
        System.out.println("UserService add-------");
        userDao.add();
    }
}
@Repository(value = "userDaoImpl1")
public class UserDaoImpl implements UserDao{
    @Override
    public void add() {
        System.out.println("UserDao add-----");
    }
}

(3) @Resource : 可以根据类型注入,可以根据名称注入

    @Resource  //根据类型进行注入
    private UserDao userDao;
    @Resource(name = "userDaoImpl1")	//根据名称进行注入
    private UserDao userDao;

(4) @Value : 注入普通类型属性

@Service
public class UserService {

    @Value(value = "张三")
    private String name;
    
    @Resource(name = "userDaoImpl1")
    private UserDao userDao;

    public void add() {
        System.out.println("UserService add-------" + name);
        userDao.add();
    }
}

结果:

com.at.spring5.service.UserService@38c5cc4c
UserService add-------张三
UserDao add-----

六,完全注解开发
1,创建配置类,代替 xml 配置文件

@Configuration  //作为配置类,代替 xml 配置文件
@ComponentScan(basePackages = {"com.at"})   //    等价于<context:component-scan base-package="com.at"></context:component-scan>
public class SpringConfig {
}

2,测试类

    @Test
    public void testService() {
        //加载配置类
        ApplicationContext context =
                new AnnotationConfigApplicationContext(SpringConfig.class);
        UserService userService = context.getBean("userService", UserService.class);
        System.out.println(userService);
        userService.add();
    }
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值