Spirng框架的入门----IOC控制反转与DI依赖注入的三个阶段

前言:什么是Spring框架?

Srping框架是一款基于JavaEE应用程序开发的开源的、轻量级的开发框架,以IOC(inverse of control)控制反转 和AOP(Aspect oriented programming)面向切面编程为内核,为java应用程序提供了组件管理服务,用于组件间的解耦,其主要目的是为了简化企业级应用程序的开发,促进低耦合,可扩展,可维护的代码。


什么是IOC?

IOC(inverse of control)控制反转:其核心理念是将对象的控制权交给Spring框架管理,由Spring框架根据配置文件和注解统一管理Bean对象的创建和对象之间的依赖关系,是Spring框架的核心思想之一,主要作用是降低程序之间的耦合性。

  • 控制 :指的是对象创建(实例化、管理)的权力
  • 反转 :控制权交给外部环境(Spring框架、IoC容器)

什么是IOC容器

SpringIOC容器是实现IOC设计模式的一个重要组件,用来创建Bean对象并管理Bean对象的生命周期,并根据配置文件和注解,管理容器中的每一个对象和对象间的依赖关系,属于Spring中的Core核心板块。
IOC容器内部是一个ConCurrentHashMap来维护了一个Beandefinition对象,该对象用来封装Spring对一个bean的所有配置信息(类名、属性、构造方法、依赖等)。


什么是Spring DI

Dependecy in 依赖注入:是SrpingIOC控制反转设计模式的一个具体实现,用于实现和维护对象间的依赖关系,就是在程序运行过程中,将一个对象依赖的其他对象注入到这个对象中,从而实现注入的思想理念。


Spring中的Bean

简单来说,Bean就是IOC容器管理的对象
Bean就是Spring容器管理的java对象
通过配置文件或者注解,告诉IOC容器需要帮助管理哪些对象


一.使用springIOC容器管理javaBean步骤:

  1. 创建JavaBean
  2. 将类注入spring容器
    配置语法:
<bean id="唯一标识" class="类的完全限定名称"></bean>
例如
<bean id="student" class="com.apesource.pojo.Student"></bean>
  1. 测试:

    3.1加载spring主配置文件获取核心对象
    ApplicationContext applicationContext = new ClassPathXmlApplicationContext(“beans.xml”);
    3.2让spring以解耦的方式进行对象的实例化返回用户
    applicationContext.getBean(“id”);


二.ID依赖注入的三个阶段:

1.基于XMl文件的依赖注入

DI实现方式:

set注入=通过set方法维护对象之间的依赖关系

  • 给属性提供set方法
  • 在bean标签内部开启配置
    配置位置:此位置
    配置语法:<property 属性名=“属性值”>
  • 配置属性:
    name======》属性名称
    value=====》属性值
    ref=======》属性值的引用
<bean id="student" class="com.apesource.pojo.Student">
        <property name="stuName" value="张三丰"></property>
        <property name="stuHobby" value="RAP"></property>
        <property name="stuAge" value="100"></property> </bean>

构造注入=通过构造方法维护对象之间的依赖关系

  • 类中需要提供一个对应参数列表的构造函数;

  • 在bean标签内部开启配置

    配置位置:此位置
    配置语法:<constructor-arg 属性名=“属性值” >

  • 属性:
    index:指定参数在构造函数参数列表的索引位置
    type:指定参数在构造函数中的数据类型
    name:指定参数在构造函数中的名称 用这个找给谁赋值
    =上面三个都是找给谁赋值,下面两个指的是赋什么值的========
    value:它能赋的值是基本数据类型和String 类型
    ref:它能赋的值是其他 bean 类型,也就是说,必须得是在配置文件中配置过的 bean

  <!--注入student类方式1 name-->
        <bean id="student1" class="com.apesource.pojo.Student">
            <constructor-arg name="stuName" value="GGBond"></constructor-arg>
            <constructor-arg name="stuAge" value="8"></constructor-arg>
        </bean>
        <!--注入student类方式2 index-->
        <bean id="student2" class="com.apesource.pojo.Student">
            <constructor-arg index="0" value="GGBond"></constructor-arg>
            <constructor-arg index="1" value="8"></constructor-arg>
        </bean>
        <!--注入student类方式3 type-->
        <bean id="student3" class="com.apesource.pojo.Student">
            <constructor-arg type="java.lang.String" value="GGBond"></constructor-arg>
            <constructor-arg type="int" value="8"></constructor-arg>
        </bean>

2.基于annonation注解+xml文件的依赖注入

将基于xml标签注入类的形式更换成了注解的形式:

  <bean id="" class="" init-method="" destroy-method="" scope="" autowire="">
        <property></property>
        <constructor-arg></constructor-arg>
    </bean>

替换为一些更加方便的注解+xml文件的形式:
第一类:注入类
1.@Component:将注解所修饰的类注入spring容器
2.@Repository 注入数据访问层
3.@Service 注入业务层
4.@Controller 注入控制层
语法:@Component(value = “id”)
如果省略value="id"默认注入的id为类的名称且首字母小写

@Controller
public class UserControllerImpl implements UserController {
......
}

注意:不可以单独使用,需要配置xml文件
<context:component-scan base-package=“”></context:component-scan>

 <!--@Component需要的包扫描-->
 <context:component-scan base-package="com.XXXXXX"></context:component-scan>

第二类:注入数据
1.@Value():向属性注入基本类型与String
语法:@Value(“数据”) @Value(“${key}”)
虽然使用了注解的方式注入值,但还是硬编码,不推荐

 	@Value("杨老师")
    private String Name;
    @Value("18")
    private  int age;
 @Value("${msg1}")//el表达式
    private  String stuname;
    @Value("${msg2}")
    private  int stuage;

注意:不可以单独使用,需要配置xml文件
<context:property-placeholder location=“”></context:property-placeholder>

<!--@value需要的资源位置-->
<context:property-placeholder location="msg.properties"></context:property-placeholder>

2.@Autowired():自动装配属性
含义:通过“set”方法【set方法可以省略】,按照“类型”自动装配,如果类型冲突则按照"名称"装配

 @Autowired
 UserDao userDao;

注意:@Autowired()注解默认按照类型进行自动装备
1.按类型装配如果冲突切换为名称装配
2.按类型装配如果冲突切换为名称装配,如果名称也没有则会抛异常
NoUniqueBeanDefinitionException
3.按类型装配没一个匹配
NoSuchBeanDefinitionException

第三类:其他注解

  1. @Primary:在类型装配冲突的情况下,此注解所修饰的类作为首选项,作用于类,不能单独用
@Primary
public class UserCopyDaoImpl implements  UserDao{
    public void save(){
        System.out.println("dao层");
    }
}
  1. @Qualifier按照名称装配,作用于属性,不能单独用
 @Autowired
 @Qualifier(value = "userDaoImpl")
 UserDao userDao;
  1. @Resource:按照名称装配,作用于属性,单独用
@Resource(name = "userDaoImpl")
UserDao userDao;
  1. @Scope:作用域,作用于类,不能单独用
@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
public class UserServiceImpl implements UserService 
  1. @PreDestroy 含义:替换destory-method,作用于方法,单独用
@PreDestroy
public void  dodestory(){
        System.out.println("属性销毁");
    }

6.@PostConstruct:替换init-method,作用于方法,单独用

@PostConstruct
public  void doinit(){
        System.out.println("属性初始化");
    }

3.基于annonation注解+javaConfig配置类的依赖注入

在Spring3.0版本之后,Spring为我们提供了全新的配置方案,就是annonation注解+javaConfig配置类的形式。在之前的xml配置文件中,其底层实现逻辑也是根据xml的解析器对象,将xml配置文件转换成配置类的形式来帮我们实现配置,而javaConfig配置类则能跳过解析的步骤,更加方便的为程序进行配置。
在javaConfig3.0版中比较重要的注解有:

  1. @Configuration:用这个注解修饰的类才是配置类,替换了原来的xml配置文件
  2. @ComponentScan():替代ComponentScan标签做注入类注解需要的包扫描
  3. @PropertySource():替代property-placeholder标签做资源文件加载
  4. @import():导入其他配置类
@Configuration
@ComponentScan(basePackages = {"com.apesource"})
@Import(DataSourceConfig.class)
public class SpringConfig {

}
@Configuration
@PropertySource(value = "classpath:jdbc.properties")
public class DataSourceConfig {

}
  1. @Bean: 注入类的新注解,作用于方法上,单独使用,无需扫描,可以注入java核心类库中的类
    方法返回值为class,方法参数名为id
@Configuration
public class SpringConfig {
    //向容器中注入id为creatStu且class为Studetn的类
    @Bean
    public Student creatStu(){
        return new Student();
    }
    //向容器中注入id为stu且class为Studetn的类
    @Bean(name = "stu")
    public Student creatStus(){
        return new Student();
    }
    //向容器中注入Java核心类库中的类
    @Bean
    public Date date(){
        return new Date();
    }
}

使用@Bean注解也可以在方法中实现依赖注入,通过有参构造方法传参来实现:

public class UserControllerImpl implements UserController {
		UserService userService;
		public UserControllerImpl(UserService userService) {
   			 this.userService = userService;
   			 .....
		}
}
......
  @Configuration
public class SpringConfig {
    //方法1
    @Bean
    public UserDao userDao(){
        return new UserDaoImpl();
    }
    @Bean
    public UserService userService(){
        return new UserServiceImpl(userDao());
    }
    @Bean
    public UserController userController(){
        return  new UserControllerImpl(userService());
    }
    //方法2
    @Bean
    public UserDao userDao(){
        return new UserDaoImpl();
    }
    @Bean
    public UserService userService(/*@Autowired*/UserDao dao){
        return new UserServiceImpl(dao);
    }
    @Bean
    public UserController userController(UserService service){
        return  new UserControllerImpl(service);
    }

}

注意:
ClassPathXmlApplicationContext()实现类是通过类路径下的配置文件来获取容器对象
AnnotationConfigApplicationContext()实现类是通过加载配置类来获取容器对象


总结

  • 将所有的javaBean注入spring容器进行“解耦”管理,spring万物皆为bean;
  • Spring第一大核心思想IOC控制反转 DI依赖注入
  • spring配置方案经历了三代变化:
    xml====>annonation+xml===>annonation+javaConfig配置类
  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值