zoukankan      html  css  js  c++  java
  • spring学习总结(一)_Ioc基础(中)

    本篇文章继续上篇文章讲解Ioc基础,这篇文章主要介绍使用spring注解配置Ioc

    上篇文章主要是通过xml配置文件进行Ioc的配置。这次进行改造下,通过注解进行配置

    首先先看一个简单的demo

    简单demo

    • 构建maven项目
    • pom文件如下
    <properties>
            <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
            <spring.version>4.3.0.RELEASE</spring.version>
        </properties>
        <dependencies>
            <dependency>
                <groupId>junit</groupId>
                <artifactId>junit</artifactId>
                <scope>test</scope>
                <version>4.10</version>
            </dependency>
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-context</artifactId>
                <version>${spring.version}</version>
            </dependency>
            <dependency>
                <groupId>org.aspectj</groupId>
                <artifactId>aspectjweaver</artifactId>
                <version>1.8.9</version>
            </dependency>
            <dependency>
                <groupId>cglib</groupId>
                <artifactId>cglib</artifactId>
                <version>3.2.4</version>
            </dependency>
        </dependencies>
    
    • BookDao.java
    package com.kevin.spring.demo1.dao;
    
    /**
     * 书籍dao
     */
    public interface BookDao {
    
        /**
         * 添加图书
         * @param book
         * @return
         */
        String addBook(String book);
    }
    
    
    • BookDaoImpl.java
    package com.kevin.spring.demo1.dao.impl;
    
    import com.kevin.spring.demo1.dao.BookDao;
    import org.springframework.stereotype.Component;
    
    /**
     * 图书实现类
     */
    @Component(value = "book")
    public class BookDaoImpl implements BookDao {
        public String addBook(String book) {
            return "添加图书" + book + "成功";
        }
    }
    
    

    在类的开头使用了@Component注解,它可以被Spring容器识别,启动Spring后,会自动把它转成容器管理的Bean。id 为 book。注意这里我指定了value值

    • book.xml
    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
           xmlns:context="http://www.springframework.org/schema/context"
           xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
        <context:component-scan base-package="com.kevin.spring.demo1"></context:component-scan>
    </beans>
    

    这里 增加了注解扫描的范围,指定了demo1包

    • 测试业务类
    package com.kevin.spring.demo1.service;
    
    import com.kevin.spring.demo1.dao.impl.BookDaoImpl;
    import org.springframework.context.ApplicationContext;
    import org.springframework.context.support.ClassPathXmlApplicationContext;
    
    /**
     * 业务类
     */
    public class BookService {
        private BookDaoImpl bookDao;
    
        public void addBook(String bookName) {
            ApplicationContext ctx = new ClassPathXmlApplicationContext("book.xml");
            bookDao = ctx.getBean("book", BookDaoImpl.class);
            String resout = bookDao.addBook(bookName);
            System.out.println(resout);
        }
    
        public static void main(String[] args) {
            new BookService().addBook("JAVA");
        }
    }
    
    

    运行结果

    信息: Loading XML bean definitions from class path resource [book.xml]
    添加图书JAVA成功
    

    我们已经完成一个简单的demo,当然只学习这些是不够的,我们还要继续挖掘每个细节

    @Component注解

    上面的demo中我们指定了一个value值,如果不指定value值的话,他默认是什么呢?

    修改BookDaoImpl.java文件,将value值删除

    /**
     * 图书实现类
     */
    @Component
    public class BookDaoImpl implements BookDao {
        public String addBook(String book) {
            return "添加图书" + book + "成功";
        }
    }
    
    

    修改测试类

    package com.kevin.spring.demo1.service;
    
    import com.kevin.spring.demo1.dao.impl.BookDaoImpl;
    import org.springframework.context.ApplicationContext;
    import org.springframework.context.support.ClassPathXmlApplicationContext;
    
    /**
     * 业务类
     */
    public class BookService {
        private BookDaoImpl bookDao;
    
        public void addBook(String bookName) {
            ApplicationContext ctx = new ClassPathXmlApplicationContext("book.xml");
            bookDao = ctx.getBean("bookDaoImpl", BookDaoImpl.class);
            String resout = bookDao.addBook(bookName);
            System.out.println(resout);
        }
    
        public static void main(String[] args) {
            new BookService().addBook("JAVA");
        }
    }
    
    

    注意下,getBean()方法部分

    运行结果

    信息: Loading XML bean definitions from class path resource [book.xml]
    添加图书JAVA成功
    

    结果证明,如果没有写value的话,默认是该类名字且首字母小写

    xml配置文件

        <context:component-scan base-package="com.kevin.spring.demo1" resource-pattern="">
            <context:exclude-filter type="" expression=""></context:exclude-filter>
            <context:include-filter type="" expression=""></context:include-filter>
        </context:component-scan>
    

    如上面代码所示

    • resource-pattern:对指定的基包下面的子包进行选取
    • include-filter:指定需要包含的包
    • exclude-filter:指定需要排除的包
      • expression:表示过滤的表达式
      • type :表示采的过滤类型 共5种类型(如下所示)
    Filter Type Examples Expression Description
    annotation org.example.SomeAnnotation 注解了SomeAnnotation的类
    assignable org.example.SomeClass 所有扩展或者实现SomeClass的类
    aspectj org.example..*Service+ AspectJ语法表示org.example包下所有包含Service的类及其子类
    regex org.example.Default.* Regelar Expression,正则表达式
    custom org.example.MyTypeFilter 通过代码过滤,实现org.springframework.core.type.TypeFilter接口

    作用域scope

    上篇文章,我们知道在xml中bean中可以配置scope 且默认为singletion,我们看看采用注解的时候是不是默认也是singleton

    修改代码

    public class BookService {
        private BookDaoImpl bookDao;
        private BookDaoImpl bookDao1;
    
        public void addBook(String bookName) {
            ApplicationContext ctx = new ClassPathXmlApplicationContext("book.xml");
            bookDao = ctx.getBean("bookDaoImpl", BookDaoImpl.class);
            bookDao1 = ctx.getBean("bookDaoImpl", BookDaoImpl.class);
            System.out.println(bookDao == bookDao1);
            String resout = bookDao.addBook(bookName);
            System.out.println(resout);
        }
    
        public static void main(String[] args) {
            new BookService().addBook("JAVA");
        }
    }
    

    运行结果

    true
    添加图书JAVA成功
    

    如果我想要修改scope 怎么弄呢?
    可以增加@Scope(value ="prototype" ),增加后运行结果为false

    Lazy延迟初始化Bean

    xml中可以设置延迟加载bean,当然注解也有
    @Lazy

    初始化回调注解

    @PostConstruct 初始化方法的注解方式 等同与在XML中声明init-method=init

    销毁回调

    @PreDestroy 销毁方法的注解方式 等同于在XML中声明destory-method=destory

    自动装配

    上面的代码中,我们都用了ApplicationContext初始化容器后获得需要的Bean,可以通过自动装配简化

    package com.kevin.spring.demo1.service;
    
    import com.kevin.spring.demo1.dao.impl.BookDaoImpl;
    import org.springframework.context.ApplicationContext;
    import org.springframework.context.support.ClassPathXmlApplicationContext;
    import org.springframework.stereotype.Component;
    import org.springframework.stereotype.Service;
    
    import javax.annotation.Resource;
    
    /**
     * 业务类
     */
    @Service
    public class BookService {
        @Resource
        private BookDaoImpl bookDao;
        @Resource
        private BookDaoImpl bookDao1;
    
        public void addBook(String bookName) {
    //        ApplicationContext ctx = new ClassPathXmlApplicationContext("book.xml");
    //        bookDao = ctx.getBean("bookDaoImpl", BookDaoImpl.class);
    //        bookDao1 = ctx.getBean("bookDaoImpl", BookDaoImpl.class);
            System.out.println(bookDao == bookDao1);
            String resout = bookDao.addBook(bookName);
            System.out.println(resout);
        }
    
        public static void main(String[] args) {
            ApplicationContext ctx = new ClassPathXmlApplicationContext("book.xml");
            BookService bookService = ctx.getBean(BookService.class);
            bookService.addBook("好好学习");
        }
    
    
    }
    
    
    • @Service用于注解业务层组件

    • @Controller用于注解控制层组件

    • @Repository用于注解数据访问组件,即DAO组件

    • @Component泛指组件,当组件不好归类的时候,我们可以使用这个注解进行注解。

    装配注解主要有:@Autowired@Qualifie@Resource,它们的特点是:

    • @Resource默认是按照名称来装配注入的,只有当找不到与名称匹配的bean才会按照类型来装配注入;

    • @Autowired默认是按照类型装配注入的,如果想按照名称来转配注入,则需要结合@Qualifier一起使用;

    • @Resource注解是又J2EE提供,而@Autowired是由spring提供,故减少系统对spring的依赖建议使用@Resource的方式;如果Maven项目是1.5的JRE则需换成更高版本的。

    • @Resource@Autowired都可以书写注解在字段或者该字段的setter方法之上

    好了,这篇文章就暂时写到这,大家玩的开心。

    代码:https://github.com/runzhenghengbin/spring-study
    参考:https://www.cnblogs.com/best/p/5727935.html#_label3

  • 相关阅读:
    Java Spring Boot VS .NetCore (十) Java Interceptor vs .NetCore Interceptor
    Java Spring Boot VS .NetCore (九) Spring Security vs .NetCore Security
    IdentityServer4 And AspNetCore.Identity Get AccessToken 问题
    Java Spring Boot VS .NetCore (八) Java 注解 vs .NetCore Attribute
    Java Spring Boot VS .NetCore (七) 配置文件
    Java Spring Boot VS .NetCore (六) UI thymeleaf vs cshtml
    Java Spring Boot VS .NetCore (五)MyBatis vs EFCore
    Java Spring Boot VS .NetCore (四)数据库操作 Spring Data JPA vs EFCore
    Java Spring Boot VS .NetCore (三)Ioc容器处理
    Java Spring Boot VS .NetCore (二)实现一个过滤器Filter
  • 原文地址:https://www.cnblogs.com/zhenghengbin/p/10098361.html
Copyright © 2011-2022 走看看