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

posted @ 2018-12-10 18:57  Kevin_zheng  阅读(325)  评论(0编辑  收藏  举报