Spring -ioc--基于注解方式

173 阅读5分钟

Spring -ioc--基于注解方式

一.基于注解方式的ioc配置:

IoC和DI都是在IoC容器中进行的,在外部:我们只需要提供类的信息即可(组件类)

学习目标:
  1.如何在类上加注解
  2.如何在xml中配置 生效包的信息;

1.注解概述:

1.注解:注解和xml文件一样,注解本身并不能执行,注解仅仅是一个标记;
        具体功能就是:框架检测到注解标记的位置,然后针对这个位置按照注解标记的功能来执行;
        
2.扫描:Spring 为了知道程序员在哪些地方标记了什么注解,就需要通过扫描的方式,来进行检测。然后根据注解进行后续操作。       
  在xml文件中配置!!!

2.组件添加标记注解

将组件配置到ioc容器之中:
    我们可以直接使用注解进行配置 ,就不用用使用<bean>了
    第(1)步:标记注解:eg:@Component   
    第(2)写一个配置文件,指定扫描包
   
  (1)
  注解:
  @Component             
  |@Repository|       该注解用于将数据访问层(Dao 层)其功能与 @Component 相同。
  @Service            用在service层
  @Controller         用在Controller层
  
  eg:
        1.注解@Component就相当于原来的<bean>
        2.本质上:这几个注解作用相同,我们只是可以根据这些组件来区分一下:是哪层的组件;
        3.使用:直接将注解放到对应的类上即可!!!
        4.加上注解之后:beanId(默认)标识就是类名的首字母小写
        eg: 
            如何(指定)注解(指定注解名字):@Component(value="egz");
            或者: @Component("egz");
        
  (2)指定扫描包:
        
        三种配置方式!!!
           <!--普通配置包扫描:(最常用!!!)-->
    <!--<context:component-scan base-package="a:指定ioc容器去哪些包下查找注解类;
    b:base-package可以指定多个包:eg:包1,包2..."/>
    c:指定包就相当于指定了包的所有类
    -->
        
    <context:component-scan base-package="com.atguigu.ioc_01"/>

           <!--2.指定包,但排除指定注解-->
    <context:component-scan base-package="com.atguigu.ioc_01">
        <!--排除包下的指定注解:以排除Repository为例-->
        <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Repository"/>

    </context:component-scan>

        
         <!--3.指定包,指定含注解-->
    <context:component-scan base-package="com.atguigu" use-default-filters="false">
        <!--base-package="com.atguigu"这句话默认是:扫描包下的全部注解
          我们可以在后面加上:use-default-filters="false":指定包的所有注解先不生效
          最后再根据包含的生效
        -->
        <!--比如我们只想要R注解:即只扫描这个com.atguigu包下的R注解,其它不要-->
        <context:include-filter type="annotation" expression="org.springframework.stereotype.Repository"/>

    </context:component-scan>

二:扩展:周期方法和作用域注解

1.周期方法:

周期方法:在指定的时间执行的代码:
   eg:在创建组件之后:调用init()
       销毁组件之前:调用destroy()
       可以在方法中做一些初始化/销毁工作
       
       
如何完成周期方法和作用域的配置:~!!!!!!!!!!!!

1.
  如何使用注解方式在ioc容器中配置周期方法
   a:准备组件类:将周期方法(init,destroy)放入类中:在组件类上使用注解eg:@Component将组件类放入ioc容器中
   b:在对应的“ 方法 ”上方加上“ 注解 ”
      @PostConstruct  //注解制指定初始化方法
      @PreDestroy //注解指定销毁方法
      
   /注意:周期方法:命名随意,但必须是public void且没有形参
   
   
   c:如何使用组件配置作用域:
      :在类上面使用注解 @Scope@Scope(scopeName = ConfigurableBeanFactory.SCOPE_SINGLETON) //单例,默认值
         @Scope(scopeName = ConfigurableBeanFactory.SCOPE_PROTOTYPE) //多例  二选一
         
         注意:单例会调用destroy方法
              多例不会管destroy

三:使用注解进行DI配置:引用其它组件(对象)

1.如何实现DI配置:

我们想要将UserController引用UserService组件:
   a: 在UserService类中:(定义全局变量):private UserService userService;(使用接口定义全局变量);
   b: 直接在UserController层的属性private UserService userService;上面  添加  “ @Autowired  ” 
     (ioc会根据类型自动装配!!!)
    //使用“ 自动装配 ” 注解@Autowired注入
    //这个注解是加在“成员变量”上的,不需要set方法,就相当于对属性/成员变量进行赋值操作:将组件赋值给组件;
    //执行过程:ioc直接找对应类型的组件,找到以后直接进行装配:将组件赋值给组件;

2.代码实现


//UserService接口

public interface UserService {

    public String show(); //接口中的抽象方法
}


@Service //!!!!我们是将UserServiceImpl放入ioc容器的!!

//UserService接口的实现类
public class UserServiceImpl  implements UserService{

    public String show(){  //实现接口的show方法
        return "UserServiceImpl.show()";

    }

}


//User的表述层

@Controller
public class UserController {

    @Autowired  //使用自动装配注解@Autowired注入:
    // 对属性userService直接进行操作,直接将UserService直接注入它,无需set方法!!!!!
    //工作原理:1.ioc容器查找符合类型的组件对象  2.设置给当前属性
    private UserService userService; //UserService定义成全局变量;
    //接口和实现类的对象相同:我们这里一般放接口!!!:即根据接口取值:放UserService


    //调用业务层的show:
    public void show(){

    }

}

注意:
1. @Autowired 标记位置:
     a:成员变量(最常用)
     b:构造器
     c:setter方法
     
2.在成员变量上方加上@Autowired:它会根据类型进行自动装配(将组件注入组件)
   默认情况下:必须要有被注入的bean,没有就报错:
(1)有1个bean,就可以正常装配(将bean注入)
(2)  如果有多个bean:默认会根据Autowired对应成员属性名当中benaID进行查找指定的bean
(3)但如果成员变量的名字和这几个bean都不同/无关:查找不到
    1..使用@Qualifer注解指定bean的名称: @Qualifer(value="BeanId");
    :进行指定具体使用哪一个UserService类(组件)进行装配;(必须配合@Autowired使用)
    2..使用整合注解:@Resource注解=@Autowired+Q注解
      但是:是java提供的,由spring实现
        使用方法:
       导入依赖
       @R(name="userServiceImp");
     
     

3.@Value注解:

如何对直接属性的DI配置:
   1.直接属性赋值:DI动作:直接赋值即可,不用加@value注解
   2. @value主要意义:读取外部的配置文件(在组件类中读取变量);eg:.properties
              a:声明配置文件
              b:将配置文件引入ioc容器中
              c:在类上相应的属性上面加@value注解
               @value("${key}")
             就可以在组件类中读取变量password,username
   3. 注意:默认值语法:当外部文件中没有 名称 eg:username,password,我们可以指定一个默认值:@Value("${key value:默认值}")

四:基于注解和xml方式整合三层架构案例

回顾:

回顾基于注解方式进行DI和IOC.jpg

想要将那个放入ioc:使用对应的注解:eg:@Component @Servcie @Controller @R
想要DI:@Autowired