Spring框架(IOC篇)

1.spring是轻量级的开源的javaEE框架

2.spring可以解决企业应用开发的复杂性

3.spring有两个核心部分:

(1) IOC:控制反转,把创建对象的过程交给Spring进行管理

(2) AOP:面向切面,不修改源代码进行功能增强

4.spring框架特点:

(1)方便解耦,简化开发

(2)AOP编程支持

(3)方便程序的测试

(4)方便和其他框架整合

(5)方便进行事物的操作

(6)降低API的开发难度

5.spring5最新版本

入门案例

网址:spring.io

1.下载spring5

(1)使用5.2.6 稳定版本

(2)下载地址

JFrog

2.idea创建项目

3.导入Spring5的相关jar包

4.创建普通的类,在这个类中创建方法

5.创建Spring配置文件,在配置文件中配置创建的对象

6.进行代码测试

二.IOC容器

(1)IOC底层原理

(2)IOC接口(BeanFactory)

(3)IOC操作Bean管理(基于xml方式)

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

IOC(概念和原理)

1.什么是IOC

(1)控制反转,把对象的创建和对象之间的调用过程,交给Spring进行管理。

(2)使用IOC的目的:为了降低耦合度

(3)做的入门案例就是IOC的实现

2.IOC底层原理

(1)xml解析,工厂模式,反射

3.画图讲解IOC底层原理

图片见文件

IOC接口

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

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

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

*加载配置文件的时候不会创建对象,再获取对象使用的才会创建对象

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

*加载配置文件的时候就会把配置文件对象进行创建

3.ApplicationContext接口有实现类

两个主要的实现类

(1)FileSystemXmlApplicationContext

(2)ClassPathXmlApplicationContext

IOC操作Bean管理

1.什么是Bean管理

Bean管理指的是两个操作

(1)Spring创建对象

(2)Spring注入属性

2.Bean管理操作有两种方式

(1)基于xml配置文件方式实现

(2)基于注解方式实现

IOC操作Bean管理(基于xml方式)

1.基于xml方式创建对象

<!--配置User对象创建-->
<bean id="user" class="com.spring.User"></bean>

(1)在Spring配置文件中,使用bean标签,标签里添加对应的属性,就可以实现

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

*id属性:唯一标识

*class属性:类全路径(包类路径)

(3)创建对象的时候,默认也是执行无参数构造方法完成对象创建

2.基于xml方式注入属性

(1)DI:依赖注入,就是注入属性

第一种:使用set方式注入

(1)创建类,定义属性和set方法

//创建属性
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.spring.Book">
<!--
    使用 property 完成属性注入
    name:类里面的属性名称
    value:向属性里面注入值
-->
    <property name="bname" value="易筋经"></property>
    <property name="bauthor" value="达摩老祖"></property>
</bean>
@Test
public void testBook1(){
    //1.加载spring配置文件
    ApplicationContext context = new ClassPathXmlApplicationContext("bean1.xml");
    //2.获取配置创建的对象
    //user是bean1.xml id的值
    Book book = context.getBean("book", Book.class);
    System.out.println(book);
    book.test();
}

第二种:有参构造注入

(1)创建类,定义属性,创建属性对应的有参数的构造方法

//属性
String oname;
String address;
//有参数的构造
public Orders(String oname, String address) {
    this.oname = oname;
    this.address = address;
}
public void Test(){
    System.out.println(oname+""+address);
}

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

<!--3.有参数的注入-->
<bean id="orders" class="com.spring.Orders">
    <constructor-arg name="oname" value="abc"></constructor-arg>
    <constructor-arg name="address" value="China"></constructor-arg>
</bean>

3.p名称空间注入

(1)使用p名称空间注入,在bean标签里面进行操作

xmlns:p="http://www.springframework.org/schema/p"

IOC操作Bean管理(xml注入其他类型属性)

1.字面量

(1)null值

<!--null值-->
<property name="address">
       <null/>
</property>

(2)属性值包含特殊符号

<!--属性值中包含特殊符号
1.把<>括号进行转义
2.把代特殊符号内容写到CDATA
-->
<property name="address">
    <value><![CDATA[<<南京>>]]></value>
</property>

2.注入属性-外部Bean

(1)创建两个类service类和dao类

(2)在service调用dao里面的方法

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

(3)在Spring配置文件中进行配置

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

3.注入属性-内部Bean和级联赋值

(1)一对多关系:部门和员工

一个部门有多个员工,一个员工属于一个部门

部门是一,员工是多

(2)在实体类之间表示一对多的关系

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 class Dept {
    private String dname;
​
    public void setDname(String dname) {
        this.dname = dname;
    }
}

(3)在Spring配置文件中进行配置

<!--    内部Bean-->
<bean id="emp" class="com.bean.Emp">
<!--设置两个普通属性-->
    <property name="ename" value="lucy"></property>
    <property name="gender" value="女"></property>
    <!--设置对象类型属性-->
    <property name="dept">
        <bean id="dept" class="com.bean.Dept">
            <property name="dname" value="安保部"></property>
        </bean>
    </property>
</bean>

4.注入属性-级联赋值

(1)第一种写法:

<!--级联赋值-->
    <bean id="emp" class="com.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.bean.Dept">
        <property name="dname" value="财务部"></property>
    </bean>

(2)第二种方法

<!--级联赋值-->
    <bean id="emp" class="com.bean.Emp">
        <!--设置两个普通属性-->
        <property name="ename" value="lucy"></property>
        <property name="gender" value="女"></property>
​
        <!--级联赋值-->
        <property name="dept" ref="dept"></property>
        <!--第二种,需要get方法-->
        <property name="dept.dname" value="财务部"></property>
    </bean>
    <bean id="dept" class="com.bean.Dept">
        <property name="dname" value="财务部"></property>
    </bean>

IOC操作Bean管理(xml注入集合属性)

1.注入数组类型的属性

2.注入List集合属性

3.注入Map集合类型属性

(1)创建类,定义数组,list,map,set类型属性,生成set方法

//1数组类型的属性
private String[] courses;
​
//2.list集合类型属性
private List<String> list;
​
//3.Map集合类型属性
private Map<String,String> maps;
​
//4.set集合类型属性
private Set<String> set;

(2)在Spring配置文件中进行配置

<!--        集合类型属性的注入-->
        <bean id="stu" class="com.spring5.Stu">
                <!--        数组类型属性的注入-->
                <property name="courses" >
                        <array>
                                <value>java</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="PHP" value="php"></entry>
                        </map>
                </property>
                <!--        set类型属性的注入-->
                <property name="set">
                        <set>
                                <value>MYSQL</value>
                                <value>Redis</value>
                        </set>
                </property>
        </bean>

4.在集合里面设置对象类型值

//学生所学多门课程
private List<Course> courseList;
​
public void setCourseList(List<Course> courseList) {
    this.courseList = courseList;
}
<!--             注入list集合类型,值是对象   -->
                <property name="courseList">
                        <list>
                                <ref bean="cource1"></ref>
                                <ref bean="cource2"></ref>
                        </list>
                </property>
<!--                创建多个cource对象-->
<bean id="cource1" class="com.spring5.Course">
        <property name="cname" value="spring5"></property>
</bean>
<bean id="cource2" class="com.spring5.Course">
        <property name="cname" value="spring"></property>
</bean>

5.把集合注入部分提取出来

(1)在spring配置文件中引入名称空间

<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">

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

<!--        1.提取list集合类型属性注入-->
    <util:list id="bookList">
        <value>易筋经</value>
        <value>九阴真经</value>
        <value>九阳真经</value>
​
    </util:list>
<!--    2.提取list集合类型属性注入使用-->
    <bean id="book" class="com.spring5.Book">
        <property name="list" ref="bookList"></property>
    </bean>

IOC操作Bean管理(FactoryBean)

1.spring有两种类型bean,一种是普通的bean,一种是工厂bean

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

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

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

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

public class MyBean implements FactoryBean<Course> {
​
    /**
     * 定义返回bean
     * @return
     * @throws Exception
     */
    @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();
    }
}
@Test
public void testCollection03(){
    ApplicationContext context = new ClassPathXmlApplicationContext("bean3.xml");
    Course course = context.getBean("myBean", Course.class);
    System.out.println(course);
}

IOC操作Bean管理(bean作用域)

1.在spring里面,设置创建的bean实例是单实例还是多实例

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

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

com.spring5.Book@6d3af739 com.spring5.Book@6d3af739

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

(1)在spring配置文件中bean标签里面有属性(scope)用于单实例还是多实例

(2)scope属性值:

第一个值:默认值,singleton,表示是单实例对象

第二个值:protitype,表示多实例对象

<bean id="book" class="com.spring5.Book" scope="prototype">
    <property name="list" ref="bookList"></property>
</bean>

com.spring5.Book@6d3af739 com.spring5.Book@1da51a35

(3)singleton和protitype区别:

第一:

singleton表示是单实例对象

protitype表示多实例对象

第二:

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

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

第三:(了解即可)

Request:表示一次请求

Session:表示一次会话

IOC操作Bean管理(bean生命周期)

1.什么是生命周期

(1)从对象的创建到对象的销毁的过程

2.bean的生命周期

(1)通过构造器创建bean实例(无参数构造)

private  String oname;
//无参数构造
​
public Orders() {
    System.out.println("第一步,执行无参数的构造方法");
}

(2)为bean的属性设置值和对其他bean的引用(调用set方法)

public void setOname(String oname) {
    this.oname = oname;
    System.out.println("第二步,调用set方法设置的值");
}

(3)调用bean的初始化的方法(需要进行配置)

//创建执行的初始化的方法
public void initMethod(){
    System.out.println("第三步,执行初始化的方法");
}
<bean id="orders" class="com.bean.Orders" init-method="initMethod" destroy-method="destoryMethod">
    <property name="oname" value="手机"></property>
</bean>

(4)bean可以使用(对象获取到了)

@Test
public void testBean(){
    //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();
}

(5)当容器关闭的时候,调用bean的销毁的方法(需要配置销毁的方法)

//创建执行的销毁的方法
public void destoryMethod(){
    System.out.println("第五步,执行销毁的方法");
}

3.演示bean生命周期

第一步:第一步,执行无参数的构造创建的bean实例

第二步:第二步,调用set方法设置的值

第三步,执行初始化的方法

第四步,获取创建的bean实例对象

第五步,执行销毁的方法

4.bean的后置处理器

(1)通过构造器创建bean实例(无参数构造)

(2)为bean的属性设置值和对其他bean的引用(调用set方法)

(3)把bean的实例传递bean后置处理器的方法postProcessBeforeInitialization

(4)调用bean的初始化的方法(需要进行配置)

(5)把bean的实例传递bean后置处理器的方法postProcessAfterInitialization

(6)bean可以使用(对象获取到了)

(7)当容器关闭的时候,调用bean的销毁的方法(需要配置销毁的方法)

@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.bean.MyBeanPost"></bean>

5.演示添加后置处理器的方法

(1)创建类:实现接口BeanPostProcessor

,创建后置处理器

IOC操作Bean管理(xml自动装配)

1.什么是自动装配

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

2.演示自动装配过程

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

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


    </bean>

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

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

	<!--
            自动装配
            bean标签属性,配置自动装配
            autowire属性值常用的两个值:
                byName根据属性名称,注入值bean的id值和类属性名一样
                byType根据属性类型注入

    -->
    <bean id="emp" class="com.autowire.Emp" autowire="byType"></bean>
    <bean id="dept" class="com.autowire.Dept"></bean>

IOC操作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="123465}"></property>
    </bean>

2.通过引入外部属性配置数据库的连接池

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

prop.driverClass=com.mysql.jdbc.Driver
prop.url=jdbc:mysql://localhost:3306/userDb
prop.userName=root
prop.password=123456

(2)把外部properties属性文件引入到spring配置文件中

*引入

<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">

**在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.什么是注解

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

(2)使用注解,注解作用在类上面,方法上面,属性上面

(3)使用注解的目的;简化xml配置

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

(1)@Component

(2)@Service

(3)@Controller

(4)@Repository

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

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

第一步:引入依赖spring-aop-.......jar

第二步:开启组件扫描

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

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

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

4.开启组件扫描细节配置

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

5.基于注解方式实现属性的注入

(1)@AutoWired:根据属性类型进行自动装配

第一步:把service和dao对象进行创建,在service和dao类上面添加注解

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

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

(2)@Qualifier:根据属性名称进行注入

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

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

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

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

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

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

6.完全注解开发

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

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

(2)编写测试类

@org.junit.Test
public void testService02(){
    //加载配置类
    ApplicationContext context =
            new AnnotationConfigApplicationContext(SpringConfig.class);
    UserService userService = context.getBean("userService", UserService.class);
    userService.add();
}
  • 5
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值