spring-ioc基础学习(2)基于注解方式的ioc配置

使用java注解的方式去实现IOC的配置

主要目标:

  • 1.学习spring基于java注解的配置方式
  • 2.熟悉spring配置注解

进行环境搭建

  • 1.创建maven项目
  • 2.引入spring依赖包

    
        org.springframework
        spring-context
        5.2.6.RELEASE
    
    
        com.alibaba
        druid
        1.1.21
    
    
        mysql
        mysql-connector-java
        5.1.47
    
    
        junit
        junit
        4.12
        test
    

  • 3.创建spring-ioc.xml文件



  • 4.创建数据库配置文件db.properties
mysql.username=mall
mysql.password=mall
mysql.url=jdbc:mysql://192.168.1.150:3306/mall
mysql.driver=com.mysql.jdbc.Driver
  • 5.创建接口和类
com.learn.controller
UserController
com.learn.service
IUserService
com.learn.service.impl
UserServiceImpl
com.learn.dao
IUserDao
com.learn.dao.impl
UserDaoImpl
com.learn.bean
User
Role

开始学习基础内容

- 1.对类进行注解标注,将bean注册到容器中有4种方式:

1.使用xml进行配置bean标签
2.使用@Component以及相关的标签进行注解后,使用包扫描方式进行注册
3.使用@Bean注解
4.使用@Import注解

本例主要使用@Component方式进行注册bean

@Component,@Controller,@Service,@Repository 四个注解性质基本相同具体如下:

@Component

@Component:spring 注册组件的注解,@Service,@Controller,@Repository等的注册功能都是由该注解提供,使用该标注后对应类将注册到容器中

源码:

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Indexed
public @interface Component {

    /**
     * The value may indicate a suggestion for a logical component name,
     * to be turned into a Spring bean in case of an autodetected component.
     * @return the suggested component name, if any (or empty String otherwise)
     */
    String value() default "";

}
@Controller

@Controller:控制器,推荐给controller层添加此注解

源码

@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Component
public @interface Controller {

    /**
     * The value may indicate a suggestion for a logical component name,
     * to be turned into a Spring bean in case of an autodetected component.
     * @return the suggested component name, if any (or empty String otherwise)
     */
    @AliasFor(annotation = Component.class)
    String value() default "";

}
@Service

@Service:业务逻辑,推荐给业务逻辑层添加此注解

源码

@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Component
public @interface Service {

    /**
     * The value may indicate a suggestion for a logical component name,
     * to be turned into a Spring bean in case of an autodetected component.
     * @return the suggested component name, if any (or empty String otherwise)
     */
    @AliasFor(annotation = Component.class)
    String value() default "";

}
@Repository

@Repository:仓库管理,推荐给数据访问层添加此注解

源码

@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Component
public @interface Repository {

    /**
     * The value may indicate a suggestion for a logical component name,
     * to be turned into a Spring bean in case of an autodetected component.
     * @return the suggested component name, if any (or empty String otherwise)
     */
    @AliasFor(annotation = Component.class)
    String value() default "";

}

从源码上看@Controller,@Service,@Repository的源码没有区别,只是名称定义不同,实现功能上三者完全一致,只是表示不同意义,方便开发者更直观的定义各个类的意义.
并且能对不同类型的bean进行一个区别,方便进行操作.

2.给各个类加上@Component相关注解

Controller类加上@Controller注解
例如:

@Controller//将组建添加到容器中--标注为控制器
public class UserController 

ServiceImpl相关的类均加上@Service注解
例如:

@Service//配置对象加载到容器中--标注为业务逻辑类
public class UserServiceImpl implements IUserService 

给DaoImpl相关类加上@Repository注解

@Repository//配置对象加载到容器中--标注为数据访问
public class UserDaoImpl implements IUserDao{

给其他需要注册的类加上@Component注解
例如

@Component
public class User 

3.在spring-ioc.xml文件中进行包扫描相关配置,将指定包内的被我们标注要注册的类均注册到spring容器中

示例:

 

//base-package为指定的包路径
context:component-scan标签

包含2个子标签,7个属性

如图:
context:component-scan源码

各个标签和属性的意义示例:

                        annotation-config="true" 
                        name-generator="org.springframework.context.annotation.AnnotationBeanNameGenerator"  
                        resource-pattern="**/*.class" 
                        scope-resolver="org.springframework.context.annotation.AnnotationScopeMetadataResolver" 
                        scoped-proxy="no" 
                        use-default-filters="false" 
                                  >
                               
            
             
            
            
            
            
            
            
            
             


两个标签的tyep类型决定加载与排除的规则,具体type类型有如下几种

/*
annotation:按照注解进行排除,标注了指定注解的组件不要,expression表示要过滤
的注解
assignable:指定排除某个具体的类,按照类排除,expression表示不注册的具体类名
aspectj:后面讲aop的时候说明要使用的aspectj表达式
custom:定义一个typeFilter,自己写代码决定哪些类被过滤掉
regex:使用正则表达式过滤
*/

参考链接https://www.cnblogs.com/fightingcoding/p/component-scan.html

4.完成包扫描后可以使用自动注入来获取bean实例

自动注入实现有两个标签分别是

@Autowired
@Resource

@Autowired标签的使用

使用@Autowired来实现自动注入

·默认优先根据类型去匹配
·如果匹配到多个类型则会按照名字匹配
·如果名又没有匹配到则会报错:
1.可以去修改属性的名字对应bean的名字:userServiceImpl
2.可以去修改Bean的名字对应属性的名字:@Service("userService")
3.可以通过@Qualifier设置属性的名字(覆盖) :@Qualifier("userServiceImpl")
4.可以通过@Primary 设置其中一个Bean为主要的自动注入Bean:@Primary
5.使用泛型作为自动注入限定符

注意:
    1. 如果只找到一个,则直接进行赋值
    1. 如果没有找到,则直接抛出异常
    1. 如果找到多个,那么会按照变量名作为id继续匹配
      1. 匹配上直接进行装配
      2. 如果匹配不上则直接报异常
    1. 当定义@Autowired的required为false时,没有匹配上是不会报错的,默认为ture
示例
    /**
     * @Autowired 也可以写在构造器上面
     * ·默认优先根据参数类型去匹配
     * ·如果匹配到多个类型则会按照参数名字匹配*/
    @Autowired
    public UserController(UserService userService) {
        this.userService = userService;
    }
   /**
     * @Autowired 也可以写在方法上面
     * ·默认优先根据参数类型去匹配
     * ·如果匹配到多个类型则会按照参数名字匹配
     * @Qualifier注解也可以作用在属性上,用来被当作id去匹配容器中的对象,如果没有此注解,那么直接按照类型进行匹配
     * @param userService*/
    @Autowired
    public void createUserSerive(@Qualifier("userServiceImpl")UserService userService){
        this.userService=userService;
    }
@Autowired源码
@Target({ElementType.CONSTRUCTOR, ElementType.METHOD, ElementType.PARAMETER, ElementType.FIELD, ElementType.ANNOTATION_TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Autowired {

    /**
     * Declares whether the annotated dependency is required.
     * 

Defaults to {@code true}. */ boolean required() default true; }

@Autowired和@Resource都可以自动进行bean注入,但是有一定区别

1.@Autowired:是spring中提供的注解,@Resource:是jdk中定义的注解,依靠的是java的标准
2.@Autowired默认是按照类型进行装配,默认情况下要求依赖的对象必须存在,@Resource默认是按照名字进行匹配的,同时可以指定name属性。
3.@Autowired只适合spring框架,而@Resource扩展性更好

5.对类的注入设置依赖关系@DependsOn

使用@DependsOn标签可以设定当前类的注入需要依赖哪些类,将对应类写入其中后,写入的类会优先于当前类加载到容器中

示例
@Repository//配置对象加载到容器中--标注为数据访问
@DependsOn({"user","role"})
public class UserDaoImpl implements IUserDao

6.将类的注入方式设置为懒加载模式@Lazy

使用@Lazy标签标注类后,该类将不会自动加载,而是在主动调用后才进行加载

示例
@Repository//配置对象加载到容器中--标注为数据访问
@Lazy//配置对象为懒加载
public class UserDaoImpl implements IUserDao

7.设定bean的作用域使用@Scope标签

@Scope标签默认为单例模式,可以根据情况设置为原型模式(多实例)

示例
@Repository//配置对象加载到容器中--标注为数据访问
@Scope(value = "prototype")
public class UserDaoImpl implements IUserDao

8.设定生命周期控制使用@PostConstruct和@PreDestroy两个注释

@PostConstruct设置的是bean初始化时的方法;
@PreDestroy设置的是bean销毁时调用的方法

示例
//    配置对象初始化时调用的方法
    @PostConstruct
    public void init(){
        System.out.println(" userDaoImpl init");
    }
//    配置对象销毁时的调用方法
    @PreDestroy
    public void destroy(){
        System.out.println("userDaoImpl destroy");
    }

总结

1.bean注册到容器中的方式
2.@Component的细节和使用
3.包扫描配置方式context:component-scan
4.自动注入@Autowired和@Resource
5.对类的注入设置依赖关系@DependsOn
6.将类的注入方式设置为懒加载模式@Lazy
7.设定bean的作用域使用@Scope标签
8.设定生命周期@PostConstruct和@PreDestroy

你可能感兴趣的:(spring-ioc基础学习(2)基于注解方式的ioc配置)