• Spring


    尚硅谷Spring框架视频教程(spring5源码级讲解)_哔哩哔哩_bilibili

    Spring框架概述

    1. Spring是轻量级的开源的JavaEE框架
    2. Spring可以解决企业应用开发的复杂性
    3. Spring有两个核心部分:IOC和Aop
      1. IOC:控制反转,把创建对象过程交给Spring进行管理
      2. Aop:面向切面,不修改源代码进行功能增强
    4. Spring特点:
      1. 方便解耦,简化开发
      2. Aop编程支持
      3. 方便程序测试
      4. 方便和其他框架进行整合
      5. 方便进行事务操作
      6. 降低API开发难度

    入门案例

    下载Spring5

    https://repo.spring.io/release/org/springframework/spring/

    比如下载5.2.6版本(repo.spring.io

    创建工程,创建一个空的lib文件夹

    导入Spring的包

    创建普通类

    public class User {
        public void add(){
            System.out.println("ad...");
        }
    }
    

    创建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-2.0.xsd">
    
        <!--配置User对象创建-->
        <bean id="User" class="com.dy.spring5.User"></bean>
    </beans>
    
    

    进行测试代码编写

    import com.dy.spring5.User;
    import org.springframework.context.ApplicationContext;
    import org.springframework.context.support.ClassPathXmlApplicationContext;
    
    
    public class TestSpring5 {
        public static void main(String[] args) {
            //1.加载spring配置文件
            ApplicationContext context = new ClassPathXmlApplicationContext("bean1.xml");
    
            //2.获取配置创建的对象
            User user = context.getBean("user", User.class);
            System.out.println(user);
            user.add();
        }
    }
    
    

    IOC容器

    IOC底层原理

    什么是IOC

    1. 控制反转,把对象创建和对象之间的调用过程,交给Spring进行管理
    2. 使用IOC目的:为了耦合度降低
    3. 做入门案例就是IOC实现

    IOC底层原理

    xml解析、工厂模式、反射



    IOC接口(BeanFactory)

    1. IOC思想基于IOC容器完成,IOC容器底层就是对象工厂

    2. Spring提供IOC容器实现两种方式:(两个接口)

      1. BeanFactory:IOC容器基本实现,是Spring内部的使用接口,不提供开发人员进行使用。

        (加载配置文件时候不会创建对象,在获取对象(使用)才去创建对象)

      2. ApplicationContext:BeanFactory接口的子接口,提供更多更强大的功能,一般由开发人员进行使用

        (加载配置文件时候就会把在配置文件对象进行创建)

    3. ApplicationContext接口有实现类

    IOC操作Bean管理

    什么是Bean管理?

    Bean管理指的是两个操作

    1. Spring创建对象
    2. Spring注入属性

    Bean管理操作有两种方式

    1. 基于xml配置文件方式实现
    2. 基于注解方式实现

    IOC操作Bean管理(基于xml)

    基于xml方式创建对象

    1. 在spring配置文件中,使用bean标签,标签里面添加对应属性,就可以实现对象创建

    2. 在bean标签有很多属性,介绍常用的属性

      1. id属性:唯一标识
      2. class属性:类全路径(包类路径)
    3. 创建对象时候,默认也是执行无参数构造方法完成对象创建(重写构造器一定要写个无参的)

    基于xml方式注入属性

    DI:依赖注入,就是注入属性

    第一种注入方式:使用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;
        }
    
        public void testDemo(){
            System.out.println(bname + "::" + bauthor);
        }
    }
    
    步骤2:在spring配置文件中配置对象创建,配置属性注入
        <!--set方法注入属性-->
        <bean id="book" class="com.dy.spring5.Book">
            <!--使用property完成属性注入
            name:类里面属性名称
            value:向属性注入的值
            -->
            <property name="bname" value="易筋经"></property>
            <property name="bauthor" value="达摩老祖"></property>
        </bean>
    

    测试代码
    import com.dy.spring5.Book;
    import com.dy.spring5.User;
    import org.junit.Test;
    import org.springframework.context.ApplicationContext;
    import org.springframework.context.support.ClassPathXmlApplicationContext;
    
    
    public class TestSpring5 {
    
        @Test
        public void testUser() {
            //1.加载spring配置文件
            ApplicationContext context = new ClassPathXmlApplicationContext("bean1.xml");
    
            //2.获取配置创建的对象
            User user = context.getBean("user", User.class);
            System.out.println(user);
            user.add();
        }
    
        @Test
        public void testBook() {
            //1.加载spring配置文件
            ApplicationContext context = new ClassPathXmlApplicationContext("bean1.xml");
    
            //2.获取配置创建的对象
            Book book = context.getBean("book", Book.class);
            System.out.println(book);
            book.testDemo();
        }
    }
    

    第二种注入方式:使用有参数构造进行注入

    步骤1:创建类,定义属性,创建属性对应有参数构造方法
    public class Orders {
        //属性
        private String oname;
        private String address;
    
        //有参数构造
        public Orders(String oname, String address) {
            this.oname = oname;
            this.address = address;
        }
    
        public void ordersTest() {
            System.out.println(oname + "::" + address);
        }
    }
    
    步骤2:在spring配置文件中进行配置
        <!--有参数构造注入属性-->
        <bean id="orders" class="com.dy.spring5.Orders">
            <constructor-arg name="oname" value="电脑"></constructor-arg>
            <constructor-arg name="address" value="china"></constructor-arg>
    <!--        <constructor-arg index="0" value="电脑""></constructor-arg>   还能这么写,不过会被打 -->
        </bean>
    

    测试代码
    import com.dy.spring5.Book;
    import com.dy.spring5.Orders;
    import com.dy.spring5.User;
    import org.junit.Test;
    import org.springframework.context.ApplicationContext;
    import org.springframework.context.support.ClassPathXmlApplicationContext;
    
    
    public class TestSpring5 {
    
    
        @Test
        public void testOrders() {
            //1.加载spring配置文件
            ApplicationContext context = new ClassPathXmlApplicationContext("bean1.xml");
    
            //2.获取配置创建的对象
            Orders orders = context.getBean("orders", Orders.class);
            System.out.println(orders);
            orders.ordersTest();
        }
    }
    

    p名称空间注入(了解)

    使用p名称空间注入,可以简化基于xml配置方式

    步骤1:添加p名称空间在配置文件中
    <?xml version="1.0" encoding="UTF-8"?>
    
    <beans xmlns="http://www.springframework.org/schema/beans"
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
           xmlns:p="http://www.springframework.org/schema/p"
           xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd">
    
    步骤2:进行属性注入,在bean标签里面进行操作
        <bean id="book" class="com.dy.spring5.Book" p:bname="九阳神功" p:bauthor="某个牛人">
            
        </bean>
    

    基于xml方式注入其他类型属性

    字面量

    null值
    <property name="address">
    	<null/>
    </property>
    
    属性值包含特殊符号
    <!--1.把<>进行转义,&lt 和 &gt-->
    <property name="address" value="&lt;&lt南京&gt;&gt"></property>
        
    <!--2.把带特殊符号内容写到CDATA-->
    <property name="address">
    	<value><![CDATA[<<南京>>]]></value>
    </property>
        
    
    

    注入属性-外部bean

    1. 创建两个类 service 类和 dao 类
    2. 在 service 调用 dao 里面的方法
    3. 在spring配置文件中进行配置

    目录结构

    UserDao类

    public interface UserDao {
        public void update();
    }
    

    UserDaoImpl类

    public class UserDaoImpl implements UserDao{
        @Override
        public void update() {
            System.out.println("com.dy.spring5.dao update....");
        }
    }
    
    

    UserService类

    import com.dy.spring5.dao.UserDao;
    public class UserService {
    
        //创建userDao类型属性,生成set方法
        private UserDao userDao;
    
        public void setUserDao(UserDao userDao) {
            this.userDao = userDao;
        }
    
        public void add() {
            System.out.println("com.dy.spring5.service add......");
            //原始方式:创建UserDao对象
    //        UserDao userDao = new UserDaoImpl();
    //        userDao.update();
            userDao.update();
    
    
        }
    }
    

    bean.xml

        <bean id="userService" class="com.dy.spring5.service.UserService">
            <!--    注入userDao对象
                        name属性:类里面属性名称
                        ref属性:创建userDao对象bean标签id值
            -->
            <property name="userDao" ref="userDaoImpl"></property>
        </bean>
        
        <bean id="userDaoImpl" class="com.dy.spring5.dao.UserDaoImpl"></bean>
    

    测试类

        @Test
        public void testAdd() {
            //1.加载spring配置文件
            ApplicationContext context = new ClassPathXmlApplicationContext("bean1.xml");
    
            //2.获取配置创建的对象
            UserService userService = context.getBean("userService", UserService.class);
    //        System.out.println(userService);
            userService.add();
        }
    

    注入属性-内部bean

    (更多的还是使用外部bean,更清晰)

    一对多关系:部门和员工。部门是一,员工是多

    在实体类之间表示一对多关系,员工表示所属部门,使用对象类型属性进行表示

    步骤1:创建类
    //部门类
    public class Dept {
        private String dname;
    
        public void setDname(String dname) {
            this.dname = dname;
        }
    }
    
    //员工类
    public class Emp {
        private String ename;
        private String gender;
        //员工属于某一个部门,使用对象形式表示
        private Dept dept;
    
        public void setDept(Dept dept) {
            this.dept = dept;
        }
    
        public void setEname(String ename) {
            this.ename = ename;
        }
    
        public void setGender(String gender) {
            this.gender = gender;
        }
    
        public void add() {
            System.out.println(ename + "::" + gender + "::" + dept);
        }
    }
    
    在spring 配置文件中进行配置
    <!--内部bean-->
        <bean id="emp" class="com.dy.spring5.bean.Emp">
    <!--        设置两个普通属性-->
            <property name="ename" value="lucy"></property>
            <property name="gender" value="女"></property>
            
    <!--        设置对象类型属性-->
            <property name="dept">
                <bean id="dept" class="com.dy.spring5.bean.Dept">
                    <property name="dname" value="安保部"></property>
                </bean>
            </property>
        </bean>
    
    测试代码
        @Test
        public void testBean() {
            //1.加载spring配置文件
            ApplicationContext context = new ClassPathXmlApplicationContext("bean1.xml");
    
            //2.获取配置创建的对象
            Emp emp = context.getBean("emp", Emp.class);
    //        System.out.println(userService);
            emp.add();
        }
    

    注入属性-级联赋值

    步骤1:创建类
    //部门类
    public class Dept {
        private String dname;
    
        public void setDname(String dname) {
            this.dname = dname;
        }
    }
    
    //员工类
    public class Emp {
        private String ename;
        private String gender;
        //员工属于某一个部门,使用对象形式表示
        private Dept dept;
    
        public void setDept(Dept dept) {
            this.dept = dept;
        }
    
        public void setEname(String ename) {
            this.ename = ename;
        }
    
        public void setGender(String gender) {
            this.gender = gender;
        }
    
        public void add() {
            System.out.println(ename + "::" + gender + "::" + dept);
        }
    }
    
    在spring 配置文件中进行配置
    <!--级联赋值-->
        <bean id="emp" class="com.dy.spring5.bean.Emp">
    <!--        设置两个普通属性-->
            <property name="ename" value="lucy"></property>
            <property name="gender" value="女"></property>
            
            <!--级联赋值-->
            <property name="dept" ref="dept"></property>
        </bean>
        <bean id="dept" class="com.dy.spring5.bean.Dept">
            <property name="dname" value="财务部"></property>
        </bean>
    
    测试代码
        @Test
        public void testBean() {
            //1.加载spring配置文件
            ApplicationContext context = new ClassPathXmlApplicationContext("bean1.xml");
    
            //2.获取配置创建的对象
            Emp emp = context.getBean("emp", Emp.class);
    //        System.out.println(userService);
            emp.add();
        }
    
    注入属性-级联赋值第二种写法

    员工类里面多一个 getDept()

    //员工类
    public class Emp {
        private String ename;
        private String gender;
        //员工属于某一个部门,使用对象形式表示
        private Dept dept;
    
        public Dept getDept() {
            return dept;
        }
    
        public void setDept(Dept dept) {
            this.dept = dept;
        }
    
        public void setEname(String ename) {
            this.ename = ename;
        }
    
        public void setGender(String gender) {
            this.gender = gender;
        }
    
        public void add() {
            System.out.println(ename + "::" + gender + "::" + dept);
        }
    }
    
    <!--级联赋值-->
        <bean id="emp" class="com.dy.spring5.bean.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.dy.spring5.bean.Dept">
            <property name="dname" value="财务部"></property>
        </bean>
    

    注入集合属性

    1. 注入数组类型属性

    2. 注入List集合类型属性

    3. 注入Map集合类型属性

    创建类,定义数组、list、map、set类型属性,生成对应set方法
    import java.util.Arrays;
    import java.util.List;
    import java.util.Map;
    import java.util.Set;
    
    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;
        }
    
        public void test() {
            System.out.println(Arrays.toString(courses));
            System.out.println(list);
            System.out.println(maps);
            System.out.println(sets);
        }
    }
    
    
    在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:p="http://www.springframework.org/schema/p"
           xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd">
    
        <!--        1.集合类型属性注入-->
        <bean id="stu" class="com.dy.spring5.collectiontype.Stu">
            <!--            数组类型属性注入-->
            <property name="courses">
                <array>
                    <value>java课程</value>
                    <value>数据库课程</value>
                </array>
                <!--                list也可以-->
                <!--                <list>-->
                <!--                    <value>java课程</value>-->
                <!--                    <value>数据库课程</value>-->
                <!--                </list>-->
            </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>Redis</value>
                </set>
            </property>
        </bean>
    </beans>
    
    测试代码
    import com.dy.spring5.collectiontype.Stu;
    import org.junit.Test;
    import org.springframework.context.ApplicationContext;
    import org.springframework.context.support.ClassPathXmlApplicationContext;
    
    public class TestSpring {
    
        @Test
        public void testCollection() {
            //1.加载spring配置文件
            ApplicationContext context = new ClassPathXmlApplicationContext("bean1.xml");
    
            //2.获取配置创建的对象
            Stu stu = context.getBean("stu", Stu.class);
    //        System.out.println(userService);
            stu.test();
        }
    }
    

    注入集合属性 - 在集合里面设置对象类型值

    创建类
    //课程类
    public class Course {
        private String cname;   //课程名称
    
        public void setCname(String cname) {
            this.cname = cname;
        }
    }
    
    
    import java.util.*;
    
    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;
    
        //学生多学多门课程
        private List<Course> courseList;
    
        public void setCourseList(List<Course> courseList) {
            this.courseList = courseList;
        }
    
        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;
        }
    
        public void test() {
            System.out.println(Arrays.toString(courses));
            System.out.println(list);
            System.out.println(maps);
            System.out.println(sets);
        }
    }
    
    在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:p="http://www.springframework.org/schema/p"
           xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd">
    
        <!--        1.集合类型属性注入-->
        <bean id="stu" class="com.dy.spring5.collectiontype.Stu">
            <!--            数组类型属性注入-->
            <property name="courses">
                <array>
                    <value>java课程</value>
                    <value>数据库课程</value>
                </array>
                <!--                list也可以-->
                <!--                <list>-->
                <!--                    <value>java课程</value>-->
                <!--                    <value>数据库课程</value>-->
                <!--                </list>-->
            </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>Redis</value>
                </set>
            </property>
    
            <!--        注入list集合类型,值是对象-->
            <property name="courseList">
                <list>
                    <ref bean="course1"></ref>
                    <ref bean="course2"></ref>
                </list>
            </property>
        </bean>
    
        <!--    创建多个course对象-->
        <bean id="course1" class="com.dy.spring5.collectiontype.Course">
            <property name="cname" value="Spring5框架"></property>
        </bean>
    
        <bean id="course2" class="com.dy.spring5.collectiontype.Course">
            <property name="cname" value="MyBatis框架"></property>
        </bean>
    </beans>
    

    把集合注入部分提取出来

    创建类
    import java.util.List;
    
    public class Book {
        private List<String> list;
    
        public void setList(List<String> list) {
            this.list = list;
        }
    
        public void test() {
            System.out.println(list);
        }
    }
    
    在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-2.0.xsd
                                http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd">
    
    使用util标签完成list集合注入
    <?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-2.0.xsd
                                http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd">
    
        <!--        1.提取list集合类型属性注入-->
        <util:list id="bookList">
            <value>书1</value>
            <value>书2</value>
            <value>书3</value>
        </util:list>
    
        <!--        2.提取list集合类型属性注入使用-->
        <bean id="book" class="com.dy.spring5.collectiontype.Book">
            <property name="list" ref="bookList"></property>
        </bean>
    </beans>
    
    测试代码
    import com.dy.spring5.collectiontype.Book;
    import com.dy.spring5.collectiontype.Stu;
    import org.junit.Test;
    import org.springframework.context.ApplicationContext;
    import org.springframework.context.support.ClassPathXmlApplicationContext;
    
    public class TestSpring {
    
        @Test
        public void testCollection() {
            //1.加载spring配置文件
            ApplicationContext context = new ClassPathXmlApplicationContext("bean1.xml");
    
            //2.获取配置创建的对象
            Stu stu = context.getBean("stu", Stu.class);
    //        System.out.println(userService);
            stu.test();
        }
    
        @Test
        public void testCollection2() {
            //1.加载spring配置文件
            ApplicationContext context = new ClassPathXmlApplicationContext("bean2.xml");
    
            //2.获取配置创建的对象
            Book book = context.getBean("book", Book.class);
    //        System.out.println(userService);
            book.test();
        }
    }
    

    工厂bean

    Spring有两种类型 bean,一种普通bean,另外一种工厂bean(FactoryBean)

    普通bean:在配置文件中定义bean类型就是返回类型

    工厂bean:在配置文件定义bean类型可以和返回类型不一样

    第一步 创建类,让这个类作为工厂bean,实现接口FactoryBean

    第二步 实现接口里面的方法,在实现的方法中定义返回的bean类型

    import com.dy.spring5.collectiontype.Course;
    import org.springframework.beans.factory.FactoryBean;
    
    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 false;
        }
    }
    

    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: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-2.0.xsd
                                http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd">
    
            <bean id="myBean" class="com.dy.spring5.factorybean.MyBean">
    
            </bean>
    </beans>
    

    测试代码

        @Test
        public void test3() {
            //1.加载spring配置文件
            ApplicationContext context = new ClassPathXmlApplicationContext("bean3.xml");
    
            //2.获取配置创建的对象
            Course course = context.getBean("myBean", Course.class);
            System.out.println(course);
        }
    

    bean作用域

    单实例还是多实例

    在spring里面,默认情况下,bean是单实例对象

    测试代码如下

    @Test
        public void testCollection2() {
            ApplicationContext context =
                    new ClassPathXmlApplicationContext("bean2.xml");
            Book book1 = context.getBean("book", Book.class);
            Book book2 = context.getBean("book", Book.class);
           // book.test();
            System.out.println(book1);
            System.out.println(book2);
        }
    

    如何设置单实例还是多实例

    1. 在spring 配置文件bean 标签里面有属性(scope)用于设置单实例还是多实例
    2. scope 属性值
      1. 第一个值,默认值,singleton,表示是单实例对象
      2. 第二个值,prototype,表示是多实例对象
            <bean id="myBean" class="com.dy.spring5.factorybean.MyBean" scope="prototype">
                
            </bean>
    
    1. singleton 和 property区别

      第一,singleton单实例,prototype多实例

      第二,设置scope值是singleton时候,加载spring配置文件时候就会创建单实例对象

      ​ 设置scope值是prototype时候,不是在加载spring配置文件时候创建对象,在调用getBean方法时候创建多实例对象

    bean的生命周期

    生命周期:从对象创建到对象销毁的过程

    bean 生命周期

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

    演示 bean 生命周期

    public class Orders {
        //无参数构造
        public Orders() {
            System.out.println("第一步 执行无参数构造创建 bean 实例");
        }
        private String oname;
        public void setOname(String oname) {
            this.oname = oname;
            System.out.println("第二步 调用 set 方法设置属性值");
        }
        //创建执行的初始化的方法
        public void initMethod() {
            System.out.println("第三步 执行初始化的方法");
        }
        //创建执行的销毁的方法
        public void destroyMethod() {
            System.out.println("第五步 执行销毁的方法");
        }
    }
    <bean id="orders" class="com.atguigu.spring5.bean.Orders" initmethod="initMethod" destroy-method="destroyMethod">
        <property name="oname" value="手机"></property>
    </bean>
    
    @Test
    public void testBean3() {
    // ApplicationContext context =
    // new ClassPathXmlApplicationContext("bean4.xml");
        ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("bean4.xml");
        Orders orders = context.getBean("orders", Orders.class);
        System.out.println("第四步 获取创建 bean 实例对象");
        System.out.println(orders);
        
        //手动让 bean 实例销毁
        context.close();
    }
    

    bean 的后置处理器,bean 生命周期有七步

    1. 通过构造器创建 bean 实例(无参数构造)
    2. 为 bean 的属性设置值和对其他 bean 引用(调用 set 方法)
    3. 把 bean 实例传递 bean 后置处理器的方法 postProcessBeforeInitialization
    4. 调用 bean 的初始化的方法(需要进行配置初始化的方法)
    5. 把 bean 实例传递 bean 后置处理器的方法 postProcessAfterInitialization
    6. bean 可以使用了(对象获取到了)
    7. 当容器关闭时候,调用 bean 的销毁的方法(需要进行配置销毁的方法)

    演示添加后置处理器效果

    创建类,实现接口 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;
        }
    }
    

    配置后置处理器

    <!--配置后置处理器-->
    <bean id="myBeanPost" class="com.atguigu.spring5.bean.MyBeanPost"></bean>
    

    xml自动装配

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

    演示自动装配过程

    根据属性名称自动注入

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

    根据属性类型自动注入

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

    外部属性文件

    1. 直接配置数据库信息:

    1)配置德鲁伊连接池 (2)引入德鲁伊连接池依赖 jar 包 (druid-1.1.9.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="root"></property>
    </bean>
    
    

    2.引入外部属性文件配置数据库连接池

    (1)创建外部属性文件,properties 格式文件,写数据库信息

    (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="${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>
    
    

    IOC操作Bean管理(基于注解)

    什么是注解

    1. 注解是代码特殊标记,格式:@注解名称(属性名称=属性值, 属性名称=属性值..)
    2. 使用注解,注解作用在类上面,方法上面,属性上面
    3. 使用注解目的:简化 xml 配置

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

    1. @Component
    2. @Service
    3. @Controller
    4. @Repository

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

    基于注解方式实现对象创建

    第一步 引入依赖

    spring-aop-5.2.6.RELEASE.jar
    

    第二步 开启组件扫描

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

    第三步 创建类,在类上面添加创建对象注解

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

    开启组件扫描细节配置

    <!--示例 1
    	use-default-filters="false" 表示现在不使用默认 filter,自己配置 filter
    	context:include-filter ,设置扫描哪些内容
    -->
    <context:component-scan base-package="com.atguigu" 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.atguigu">
    	<context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
    </context:component-scan>
    

    基于注解方式实现属性注入

    1.Autowired

    @Autowired:根据属性类型进行自动装配

    1. 第一步 把 service 和 dao 对象创建,在 service 和 dao 类添加创建对象注解
    2. 第二步 在 service 注入 dao 对象,在 service 类添加 dao 类型属性,在属性上面使用注解
    @Service
    public class UserService {
        //定义 dao 类型属性
        //不需要添加 set 方法
        //添加注入属性注解
        @Autowired
        private UserDao userDao;
        public void add() {
            System.out.println("service add.......");
            userDao.add();
        }
    }
    

    2.Qualifier

    @Qualifier:根据名称进行注入

    这个@Qualifier注解的使用,和上面@Autowired一起使用

    比如一个接口有多个实现,就没有办法根据类型进行注入

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

    3.Resource

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

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

    4.Value

    @Value:注入普通类型属性

    @Value(value = "abc")
    private String name;
    

    完全注解开发

    (1)创建配置类,替代 xml 配置文件

    @Configuration //作为配置类,替代 xml 配置文件
    @ComponentScan(basePackages = {"com.atguigu"})
    public class SpringConfig {
    }
    

    (2)编写测试类

    @Test
    public void testService2() {
        //加载配置类
        ApplicationContext context
                = new AnnotationConfigApplicationContext(SpringConfig.class);
        UserService userService = context.getBean("userService",
                UserService.class);
        System.out.println(userService);
        userService.add();
    }
    

    AOP

    概念

    什么是 AOP

    1. 面向切面编程(方面),利用 AOP 可以对业务逻辑的各个部分进行隔离,从而使得 业务逻辑各部分之间的耦合度降低,提高程序的可重用性,同时提高了开发的效率。
    2. 通俗描述:不通过修改源代码方式,在主干功能里面添加新功能
    3. 使用登录例子说明 AOP

    底层原理

    AOP 底层使用动态代理,有两种情况动态代理:

    1. 第一种 有接口情况,使用 JDK 动态代理

    创建接口实现类代理对象,增强类的方法

    1. 第二种 没有接口情况,使用 CGLIB 动态代理

    创建子类的代理对象,增强类的方法

    JDK 动态代理

    使用 JDK 动态代理

    使用 java.lang.reflect.Proxy 类里面的方法创建代理对象

    调用 newProxyInstance 方法

    方法有三个参数:

    第一参数,类加载器
    第二参数,增强方法所在的类,这个类实现的接口,支持多个接口
    第三参数,实现这个接口 InvocationHandler,创建代理对象,写增强的部分

    编写 JDK 动态代理代码

    (1)创建接口,定义方法

    public interface UserDao {
    	public int add(int a,int b);
    	public String update(String id);
    }
    

    (2)创建接口实现类,实现方法

    public class UserDaoImpl implements UserDao {
         @Override
         public int add(int a, int b) {
         	return a+b;
    	}
         @Override
         public String update(String id) {
         	return id;
         }
    }
    

    (3)使用 Proxy 类创建接口代理对象

  • 相关阅读:
    JAVA帮助文档全系列 JDK1.5 JDK1.6 JDK1.7 官方中英完整版下载
    Apache HttpComponents Client 4.0快速入门/升级-2.POST方法访问网页
    HttpClient_4 用法 由HttpClient_3 升级到 HttpClient_4 必看
    Eclipse中设置编码的方式
    javadoc简介
    正则表达式:网页爬虫:从TXT中获取邮箱地址(获取的练习,缺点:一行只能匹配一个)
    Linux系统中yum 命令讲解
    查看CentOS版本信息
    Linux系统下安装JDK
    Linux基础性笔记
  • 原文地址:https://www.cnblogs.com/dongye95/p/15858283.html
Copyright © 2020-2023  润新知