Spring依赖注入

我们经常见到的控制翻转(Inversion of Control-IOC) 和依赖注入(dependency injection-DI),在Spring 环境下等同的概念,控制翻转是通过依赖注入实现的。所谓依赖注入指的是容器负责创建对象和维护对象间的依赖关系,而不是通过对象本身负责自己的创建和解决自己的依赖。

Spring IOC容器(ApplicationContext)负责创建Bean ,并通过容器将功能类Bean注入到你需要的Bean中。Spring框架提供使用Xml、注解、java配置、groovy配置实现Bean 的创建和注入。

无论是 Xml 配置、注解配置还是 java 配置,都被称为元数据,所谓元数据即描述数据的数据。元数据本身不具备任何可执行能力,只能通过外界代码来对这些元数据行解析后进行一些有意义的操作。Spring容器解析这些配置的元数据进行Bean初始化、配置和管理依赖。

声明Bean的注解:

  •  @Component 没有明确的角色
  •  @Service 在业务逻辑层(service层)使用
  • @Repository  在数据访问层(dao层)使用
  • @Controller 在表现层(MVC-->SpringMVC)使用
注入Bean的注解,一般情况下通用

  • @Autowired Spring提供的注解
  • @Inject JSR-330提供的注释
  • @Resource JSR-250提供的注释
@Autowired 、@Inject @Resource可注解在set方法上或者属性上,建议注解在属性上,有点是代码更少、层次更清晰。

一般注入规则:


从逻辑图中我们可以看出,Spring容器包含了Model层、Service层、Dao层 。 他们每一个都是Spring容器管理的一个实体类。可以通过Spring容器将一个实体类需要的另外实体类传给它。 而不采用在实体类中通过new的方式来获取实体类,因为new的方式不方便我们的使用。我们通过注入的方式,传给他需要的实体类,也就是一个实体类需要什么对象,只要被需要的对象在Spring容器管理下,我就给它什么对象,不再需要通过new的形式得到他,这样在实体类中我们就可以直接使用。

依赖注入:①注解注入

(model层)
package com.dependencyInjection_Di;

import org.springframework.stereotype.Component;

@Component  //声明Model是Spring管理的一个bean
public class Model {
    public String ModelName;
}

(service层)
package com.dependencyInjection_Di;

import com.dependencyInjection_Di.ModelMapper;
import com.dependencyInjection_Di.Model;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service(value = "modelService")  //声明ModelService是Spring管理的一个bean
public class ModelService {
    @Autowired
    ModelMapper modelMapper;
    @Autowired
    Model model;
    public void SayHello(){
        System.out.println("进入Service层");
        model.ModelName="测试完毕";
        modelMapper.SayHello(model);
    }
}
(dao层)
package com.dependencyInjection_Di;
import org.springframework.stereotype.Repository;
@Repository
public class ModelMapper {
    public void SayHello(Model model){
        System.out.print("数据持久层insert "+"\n"+model.ModelName);
    }
}

声明配置类

 
package com.dependencyInjection_Di;

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

@Configuration      //声明当前类是一个配置类
@ComponentScan("com.dependencyInjection_Di")  //使用ComponentScan自动扫描包下所有的@Service、@Component、@Repository、@Controller
public class Diconfig {
}

测试类
 
package com.dependencyInjection_Di;

import com.dependencyInjection_Di.Diconfig;
import com.dependencyInjection_Di.ModelService;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;

public class RunningTest {
    /**
     * 用到jar包
     <dependency>
         <groupId>org.springframework</groupId>
         <artifactId>spring-context</artifactId>
         <version>4.3.12.RELEASE</version>
     </dependency>
     <dependency>
         <groupId>org.springframework</groupId>
         <artifactId>spring-core</artifactId>
         <version>4.3.13.RELEASE</version>
     </dependency>
     * Spring框架本身四大原则
     * ⑴使用POJO进行轻量级和最小侵入式开发
     * ⑵通过依赖注入和基于接口编程实现松耦合
     * ⑶通过AOP和默认习惯进行声明式编程
     * ⑷使用AOP和模板(template)减少模式化代码
     * Spring所有功能的设计和实现都是基于此四大原则
     * @Configuration 声明类是配置类
     * @ComponentScan 自动扫描目录下所有带有注解的Bean
     * @Service、@Controller、@Component、@Repository  是等效的,可以根据层面选择进行标识使用
     */
    public static void main(String arg[]){
        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(Diconfig.class);
        ModelService modelService = (ModelService) context.getBean("modelService");
        modelService.SayHello();
    }
}
输出信息
 
。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。蛮多信息
信息: Refreshing org.springframework.context.annotation.AnnotationConfigApplicationContext@63ee4826: startup date [Thu Jan 18 18:14:29 CST 2018]; root of context hierarchy
进入Service层
数据持久层insert 
测试完毕
Process finished with exit code 0



依赖注入:②java配置注入

(model层)
package com.JavaDependencyInjection_Di;
public class Model
{
    public String modelName;
}
(service层)
package com.JavaDependencyInjection_Di;

import com.JavaDependencyInjection_Di.ModelMapper;
import com.JavaDependencyInjection_Di.Model;

public class ModelService {
    Model model;
    ModelMapper modelMapper;
    public void setModel(Model model){
        this.model=model;
    }

    public void setModelMapper(ModelMapper modelMapper) {
        this.modelMapper = modelMapper;
    }

    public void SayHello(){
        System.out.println("service层");
        model.modelName="Hello";
        modelMapper.SayHello(model);
    }
}
(dao层)
package com.JavaDependencyInjection_Di;
public class ModelMapper {
    public void SayHello(Model model){
        System.out.print("Dao层 \n");
        System.out.print(model.modelName);
        System.out.print("\n 测试完毕!");
    }
}

(配置类)
package com.JavaDependencyInjection_Di;

import com.JavaDependencyInjection_Di.ModelMapper;
import com.JavaDependencyInjection_Di.Model;
import com.JavaDependencyInjection_Di.ModelService;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration   //①
public class JavaConfig {
    @Bean      //②
    public Model model(){
        return new Model();
    }
    @Bean
    public ModelMapper modelMapper(){
         return new ModelMapper();
    }

    @Bean

    public ModelService modelService(){
        ModelService modelService = new ModelService();
        modelService.setModelMapper(modelMapper());  //③
        modelService.setModel(model());
        return modelService;
    }
    @Bean
    public ModelService modelService(Model model,ModelMapper modelMapper){
        ModelService modelService = new ModelService();
        modelService.setModelMapper(modelMapper); //④
        modelService.setModel(model);
        return modelService;
    }
    /**
     * ①使用@Configuration 声明当前类是一个配置类,这以为着这个类里可能含有 0 个或者多个 @Bean注解,
     *      此处没有使用包扫描,是因为所有的 Bean 都在此类中定义了
     * ②使用@Bean声明当前方法 model() 返回值是一个Bean,Bean名称是方法名
     * ③注入 ModelMapper 的 Bean 时候直接调用 modelMapper()
     * ④另一种注入方式,直接将 ModelMapper  作为参数给 modelService(),这也是Spring容器提供的极好的功能,
     *      在 Spring 容器中,只要容器中存在某个 Bean,就可以在另一个 Bean 的声明方法参数中写入
     */
}
(测试类)
package com.JavaDependencyInjection_Di;

import com.JavaDependencyInjection_Di.JavaConfig;
import com.JavaDependencyInjection_Di.ModelService;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;

public class RunningTest {
    public static void main(String arg[]){
        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(JavaConfig.class);
        ModelService modelService = context.getBean(ModelService.class);
        modelService.SayHello();
    }
}

(运行结果)

一月 18, 2018 6:31:05 下午 org.springframework.context.annotation.AnnotationConfigApplicationContext prepareRefresh
信息: Refreshing org.springframework.context.annotation.AnnotationConfigApplicationContext@7956b7c1: startup date [Thu Jan 18 18:31:05 CST 2018]; root of context hierarchy
service层
Dao层 
Hello
 测试完毕!
Process finished with exit code 0



此乃学习笔记,记录下来希望以备自己忘记,不好地方,望多加指点。



  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值