Spring框架进阶一

1. Spring-IOC

1.1 Spring对象的生命周期

1.1.1对象的生命周期的说明

  1. 对象创建

  2. 初始化数据

  3. 对象的调用使用

  4. 销毁对象

核心问题:生命周期内的方法除了实现业务的对象调用都是自动调用的,

测试准备:

编辑测试前的功能类

package com.jt.demo6;

import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;

/*spring自动为该注解标识的类,通过反射实例化对象交给
  spring容器管理,类似于@Bean注解
    @Component/@Bean区别:
  1.@Component  spring容器通过反射自动创建对象
    @Bean是用户手动自己创建的
  2.@Component  标识类的
    @Bean       标识类中的方法的
  3.@Component  对象的Id的类名首字母小写
    @Bean        对象的Id是方法名
*/
@Component
public class User {
    //1.对象的创建
    public User(){
        System.out.println("用户的对象创建成功");
    }
    //2.进行初始化操作
    @PostConstruct//初始化的注解
    public void init(){
        System.out.println("为属性赋值");
    }
    //3.进行业务的调用  业务方法,用户手动调用
    public void hello(){
        System.out.println("我爱学Java~");
    }
    //4.销毁方法
    @PreDestroy
    public void destory(){
        System.out.println("调用销毁方法,释放资源!!!");
    }
}

注解说明:

1.@PostConstruct 标识初始化方法

2.@PreDestroy 标识销毁方法

编辑测试类

注意:容器的接口里面没有提供.close( ),如果需要关闭容器则需要使用实现类中的方法

package com.jt.demo6;

import org.springframework.context.annotation.AnnotationConfigApplicationContext;

public class TestUser {
    public static void main(String[] args) {

  AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(SoringConfig.class);
        User user = context.getBean(User.class);
        User user1 =(User) context.getBean("user");

        //调用业务方法
        user.hello();
       // user1.hello();//两种方法效果一致实现写法不同
        //如果需要执行销毁方法,则需要先关闭容器的对象
        //思想:销毁动作是敏感行为,特殊处理,实现类中有关闭的方法,接口中没有
        context.close();

    }

1.2 Spring管理对象-@Component

1.2.1 @Component注解的作用

spring自动为该注解标识的类,通过反射实例化对象交给

spring容器管理,类似于@Bean注解

@Component/@Bean区别:

1.@Component spring容器通过反射自动创建对象 @Bean是用户手动自己创建的 2.@Component 标识类的 @Bean 标识类中的方法的 3.@Component 对象的Id的类名首字母小写 @Bean 对象的Id是方法名

1.2.2 @ComponentScan注解的说明

目的就是为了让Spring的注解生效,需要单独使用包扫描注解

@Configuration//表示配置类
@ComponentScan("com.jt.demo6")//包扫描
public class SoringConfig {}

2. Spring-DI(Dependency Injection)

2.1 Spring中的依赖注入

说明:依赖注入就是将Spring容器管理对象(数据),赋值给对象的属性

核心机制:如果需要使用依赖注入,则对象的属性必须要提供set方法

2.2 xml配置文件的写法

2.2.1 编辑Person类

package com.jt.demo7_id;

public class Person {
    private int id;
    private String name;

    public void sayHi(){
        System.out.println("你好呀"+id+name);
    }
    public int getId() {
        return id;
    }
	//为属性赋值必须要有set方法!!!重中之重
    public void setId(int id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

}

2.2.2 编辑xml配置文件

配置属性是使用的<property/>标签

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
    <!--
        知识点讲解:
            1.bean 被spring容器管理的对象称之为bean
            2.id    全局唯一变量一般类型首字母小写
            3.class class的路径信息,需要写全名
    -->

    <!--xml配置文件为属性赋值-->
    <bean id="person" class="com.jt.demo7_id.Person">
        <property name="id" value="100"></property>
        <property name="name"   value="新年快乐"></property>
        <property name="car" ref="car"></property>
    </bean>

2.2.3 编辑测试类

package com.jt.demo7_id;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.stereotype.Component;

@Component//将类交给Spring容器管理
public class TersPerson {
    public static void main(String[] args) {
        //创建容器对象
        ApplicationContext context = new ClassPathXmlApplicationContext("spring_id.xml");
       // ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("spring_id.xml");
        //从容器中获取对象
        Person bean = context.getBean(Person.class);
        //调用业务方法
        bean.sayHi();
      //  context.close();//关流操作
    }
}

2.3 Spring为对象赋值

2.3.1 构造Car对象

package com.jt.demo7_id;

public class Car {
    private String name;
    private String color;

    public  void go(){
        System.out.println("上我的"+color+"的"+name+"带你去浪漫的土耳其~");
    }
    public Car(){
        System.out.println("无参构造方法");
    }
    public Car(String name,String color){
        this.name=name;
        this.color=color;
        System.out.println("全参构造方法");
    }
}

2.3.2 编辑xml配置文件

管理对象是使用的<constructor-arg/>标签

 <!--1.让spring容器管理car,参数的个数,决定调用的构造方法-->
    <bean id="car" class="com.jt.demo7_id.Car">
        <constructor-arg name="name" value="奥迪RS8"></constructor-arg>
        <constructor-arg name="color" value="绿色"></constructor-arg>
    </bean>

2.3.3补充构建Person类

package com.jt.demo7_id;
​
public class Person {
    private int id;
    private String name;
    private Car car;
​
    public void sayHi(){
        System.out.println("你好呀"+id+name);
    }
    public int getId() {
        return id;
    }
​
    public void setId(int id) {
        this.id = id;
    }
​
    public String getName() {
        return name;
    }
​
    public void setName(String name) {
        this.name = name;
    }
​
    public Car getCar() {
        return car;
    }
​
    public void setCar(Car car) {
        this.car = car;
    }
    public void toGo(){
        car.go();
    }
}

2.3.4 编辑测试类

package com.jt.demo7_id;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.stereotype.Component;

@Component
public class TersPerson {
    public static void main(String[] args) {
        //创建容器对象
        ApplicationContext context = new ClassPathXmlApplicationContext("spring_id.xml");
       // ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("spring_id.xml");
        //从容器中获取对象
        Person bean = context.getBean(Person.class);
        //调用业务方法
        bean.sayHi();
        bean.toGo();
      //  context.close();//关流操作
    }
}

2.3.5 IOC/DI意义

我的理解:Spring中的IOC(控制反转)/DI(依赖注入)两种方式相互配合,实现了代码的解耦/松耦合

2.4 注入的方式说明

2.4.1 Set方法注入

说明:通过set方法为属性赋值,所以必须提供set方法才行,xml配置文件中使用的是property标签,开发中常用的是set方法注入

2.4.2 构造方法注入

说明:通过构造方法为属性赋值,所以需要提供构造方法,提醒手动写上无参构造,使用的是constructor -arg标签.

<!--1.让spring容器管理car,参数的个数,决定调用的构造方法-->
    <bean id="car" class="com.jt.demo7_id.Car">
        <constructor-arg name="name" value="奥迪RS8"></constructor-arg>
        <constructor-arg name="color" value="绿色"></constructor-arg>
    </bean>

备注:Ste和构造方法为属性赋值都是常规写法,没有好坏之分,自己习惯用哪个就行,set注入以后用的多些

2.5 Spring属性赋值-注解用法@Autowired

2.5.1编辑配置类

package com.jt.demo8_anno;

import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;

@Configuration//标记为配置类
@ComponentScan("com.jt.demo8_anno")//包扫描
public class SpringConfig {

}

2.5.2 编辑Tiger类

package com.jt.demo8_anno;

import org.springframework.stereotype.Component;
//对象套对象
@Component//将该对象交给spring容器管理,key:tiger  value:tiger对象
public class Tiger implements Pet{
    @Override
    public void hello() {
        System.out.println("虎年吉祥~");
    }
}

2.5.3 编辑User类

package com.jt.demo8_anno;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Component;

/**
 * 1.该类主要测试 注解的注入方式
 * 2.练习对象的嵌套关系
 * 3.注解的写法与xml写法的原理相同的,形式不同
 * */
@Component//把user交给spring容器管理  key:user  value:反射后的对象
public class User {//用户

    /**
     * 注解说明:
 *      1.@Autowired  自动注入
 *      规则:
 *          1.默认条件下,底层是使用set方法注入.按照类型匹配
 *          2.set方式注入也可以按照name名称进行匹配
 *          3.只要使用了这个注解,默认自动生成setxxx的方法
 *     实现原理:
 *          1.类型匹配 如果是接口,则自动匹配其实现类对象
 *          2.name名称匹配:根据spring中的key进行注入.
 *      2.@Qualifier
 *          必须和 @Autowired联用,
 *          并且需要指定value的名称,就是spring中的key
 *
 *      准则:一般情况下,Spring中都是单实现的
 **/
    @Autowired
    @Qualifier("pig")
    private Pet pet;

    public void hello(){
        pet.hello();
    }

}

2.5.4 编辑测试类

package com.jt.demo8_anno;

import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;

public class TestUser {

    public static void main(String[] args) {
        ApplicationContext context = new AnnotationConfigApplicationContext(SpringConfig.class);
        User user = context.getBean(User.class);
        user.hello();

    }
}

总结:使用注解开发后能够明显感觉到代码量少了很多,这也是注解的一大特性,减少代码冗余

2.6 拓展:多实现类的情况处理

2.6.1 异常说明

Spring中的DI注入,一般情况下采用按照类型的方式进行匹配,但是如果遇到了多实现类的情况,就会出现,报错: 一个接口匹配了多个实现类,程序异常

原因:这个是由于程序是不会自动做选择的,当面临多个选择的时候,它不知道到底选哪个所以直接报错

2.6.2 指定key进行赋值

package com.jt.demo8_anno;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Component;

/**
 * 1.该类主要测试 注解的注入方式
 * 2.练习对象的嵌套关系
 * 3.注解的写法与xml写法的原理相同的,形式不同
 * */
@Component//把user交给spring容器管理  key:user  value:反射后的对象
public class User {//用户

    /**
     * 注解说明:
 *      1.@Autowired  自动注入
 *      规则:
 *          1.默认条件下,底层是使用set方法注入.按照类型匹配
 *          2.set方式注入也可以按照name名称进行匹配
 *          3.只要使用了这个注解,默认自动生成setxxx的方法
 *     实现原理:
 *          1.类型匹配 如果是接口,则自动匹配其实现类对象
 *          2.name名称匹配:根据spring中的key进行注入.
 *      2.@Qualifier
 *          必须和 @Autowired联用,
 *          并且需要指定value的名称,就是spring中的key
 *
 *      准则:一般情况下,Spring中都是单实现的
 **/
    @Autowired
    @Qualifier("pig")
    private Pet pet;

    public void hello(){
        pet.hello();
    }

}

2.7 Spring属性赋值-@Value注解

2.7.1编辑properties配置文件

创建一个dept.properties文件

#1.数据结构  key = value
#2.其中的数据默认都是String类型,数值可以切换为Integer数值类型
#3.程序读取时,默认的字符集ISO-8859-1,不支持中文,如需要使用UTF-8

dept.id=101
dept.name=行政部

2.7.2 为属性赋值操作

package com.jt.demo9;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.PropertySource;
import org.springframework.stereotype.Component;

@Component
//当spring容器启动的时候,加载指定的配置文件,将数据保存到容器中!!!
@PropertySource(value = "classpath:/dept.properties",encoding = "utf-8")
public class Dept {

    //取值方式:从spring容器中获取数据 ${pro中的key}
    @Value("${dept.id}")
    private  Integer id;
    @Value("${dept.name}")
    private String  name;

    // @Value("101")
    //private  Integer id;
    //@Value("财务部")
    //private String  name;

    public void hello(){
        System.out.println("获取数据"+id+name);
    }

2.7.3 编辑测试类

package com.jt.demo9;

import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;

public class TestDept {

    public static void main(String[] args) {

    ApplicationContext context =  new   AnnotationConfigApplicationContext(SpringConfig.class);

        Dept dept = context.getBean(Dept.class);
        
        dept.hello();

    }
}

注解总结: 本章用到了哪些新的注解呢?

1.@ComponentScan 标记于类,包扫描,目的是为了让Spring中的注解生效

2.@PostConstruct 标记于方法,初始化注解

3.@PreDestory 标记于方法,用于销毁对象

4.@Component 标记于类,用于表示将本类交于Spring容器管理

5.@Autowired 标记于属性,按照类型注入,底层是使用的set注入,只要使用了这个注解,默认自动生成setxxx的方法不用手写

6.@Qualifier 标记于属性,按照名称注入,使用前提是需要有@Autowired ,并且需要指定value的名称,就是spring中的key,不可单独使用

7.@Value 标记于属性,格式${properties文件中的key值}

8.@PropertySource 标记于类,当spring容器启动的时候,加载指定的配置文件,将数据保存到容器中

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值