美文网首页Java
Java Spring-通过注解配置Bean

Java Spring-通过注解配置Bean

作者: 一亩三分甜 | 来源:发表于2020-01-17 17:50 被阅读0次

组件扫描(component scanning):Spring能够从classpath下自动扫描,侦测和实例化具有特定注解的组件。

特定组件包括:

@Component:基本注解,标识了一个受Spring管理的组件

@Respository:标识持久层组件

@Service:标识服务层(业务层)组件

@Controller:标识表现层组件

对于扫描到的组件,Spring有默认的命名策略:使用非限定类名,第一个字母小写。也可以在注解中通过value属性值标识组件的名称

当在组件类上使用了特定的注解之后,还需要再Spring的配置文件中声明<context:component-scan>:

base-package属性指定一个需要扫描的基类包,Spring容器将会扫描这个基类包里及其子包中的所有类。

当需要扫描多个包时,可以使用逗号分隔

如果仅希望扫描特定的类而非基包下的所有类,可使用resource-pattern属性过滤特定的类,实例:

<context:component-scan base-package="com.cloud.spring.beans" resource-pattern="autowire/*.class"/>

<context:include-filter>子节点表示要包含的目标类

<context:exclude-filter>子节点表示要排除在外的目标类

  • <context:component-scan>下可以拥有若干个<context:include-filter>和<context:exclude-filter>子节点

默认情况下接口类userRepository的bean标识名为实现类userRepositoryImpl的名字。可以通过在@Repository边上以注解的方式进行修改@Repository("userRepository"),修改为接口名bean的名字userRepository。

public class Main {
    public static void main(String[] args) {
        ApplicationContext context = new ClassPathXmlApplicationContext("beans-annotation.xml");
        TestObject to = (TestObject) context.getBean("testObject");
        System.out.println(to);

        UserController userController = (UserController) context.getBean("userController");
        System.out.println(userController);

        UserService userService = (UserService)context.getBean("userService");
        System.out.println(userService);

        UserRepository userRepository = (UserRepository) context.getBean("userRepositoryImpl");
        System.out.println(userRepository);
    }
}

public interface UserRepository {
    void save();
}
@Repository
public class UserRepositoryImpl implements UserRepository{
    @Override
    public void save() {
        System.out.println("UserRepositoryImpl Save()");
    }
}

<!-- 指定Spring IOC 容器扫描的包 -->
<context:component-scan base-package="com.cloud.spring.beans.annotation"></context:component-scan>
    
    
//输出
一月 15, 2020 6:53:56 下午 org.springframework.context.support.ClassPathXmlApplicationContext prepareRefresh
信息: Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@799f7e29: startup date [Wed Jan 15 18:53:56 CST 2020]; root of context hierarchy
一月 15, 2020 6:53:56 下午 org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
信息: Loading XML bean definitions from class path resource [beans-annotation.xml]
com.cloud.spring.beans.annotation.TestObject@64485a47
com.cloud.spring.beans.annotation.controller.UserController@25bbf683
com.cloud.spring.beans.annotation.service.UserService@6ec8211c
com.cloud.spring.beans.annotation.repository.UserRepositoryImpl@7276c8cd

修改接口实现类UserRepositoryImpl的bean的名字为UserRepository接口的bean的名字userRepository。

@Repository("userRepository")
public class UserRepositoryImpl implements UserRepository{
    @Override
    public void save() {
        System.out.println("UserRepositoryImpl Save()");
    }
}

扫描特定的类而非基包下的所有类,可使用resource-pattern属性过滤特定的类

<context:component-scan base-package="com.cloud.spring.beans.annotation"
                            resource-pattern="repository/*.class">
</context:component-scan>

        UserRepository userRepository = (UserRepository) context.getBean("userRepository");
        System.out.println(userRepository);
//输出
com.cloud.spring.beans.annotation.repository.UserRepositoryImpl@289d1c02

<context:include-filter>和<context:exclude-filter>子节点支持多种类型的过滤表达式:

类型 示例 说明
annotation com.cloud.XxxAnnotation 所有标注了XxxAnnotation的类。该类型采用目标类是否标注了某个注解进行过滤
assignable com.cloud.XxxService 所有继承或扩展XxxService的类。该类型采用目标类是否继承或扩展某个特定类进行过滤
aspectj com.cloud..*Service+ 所有类名以Service结束的类及继承或扩展它们的类。该类型采用AspecjctJ表达式进行过滤
regex com.\cloud..anno..* 所有com.cloud.anno包下的类。该类型采用正则表达式根据类的类名进行过滤
custom com.cloud.XxxTypeFilter 采用XxxTypeFilter通过代码的方式定义过滤规则。该类必须实现org.springframework.core.type.TypeFilter接口

不包含<context:exclude-filter>

        ApplicationContext context = new ClassPathXmlApplicationContext("beans-annotation.xml");

        TestObject to = (TestObject) context.getBean("testObject");
        System.out.println(to);

        UserController userController = (UserController) context.getBean("userController");
        System.out.println(userController);

        UserService userService = (UserService)context.getBean("userService");
        System.out.println(userService);

        UserRepository userRepository = (UserRepository) context.getBean("userRepository");
        System.out.println(userRepository);
        
<context:component-scan base-package="com.cloud.spring.beans.annotation">
<context:exclude-filter type="annotation" expression="org.springframework.stereotype.Repository"/>
    </context:component-scan>
//输出
一月 17, 2020 3:56:00 下午 org.springframework.context.support.ClassPathXmlApplicationContext prepareRefresh
信息: Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@799f7e29: startup date [Fri Jan 17 15:56:00 CST 2020]; root of context hierarchy
一月 17, 2020 3:56:00 下午 org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
信息: Loading XML bean definitions from class path resource [beans-annotation.xml]
Exception in thread "main" org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 'userRepository' available
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBeanDefinition(DefaultListableBeanFactory.java:687)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getMergedLocalBeanDefinition(AbstractBeanFactory.java:1207)
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:284)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:197)
    at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:1078)
    at com.cloud.spring.beans.annotation.Main.main(Main.java:28)

包含<context:include-filter>,结合属性use-default-filters="false"使用

    <context:component-scan base-package="com.cloud.spring.beans.annotation" use-default-filters="false">
        <context:include-filter type="annotation" expression="org.springframework.stereotype.Repository"/>
    </context:component-scan>
            ApplicationContext context = new ClassPathXmlApplicationContext("beans-annotation.xml");

        TestObject to = (TestObject) context.getBean("testObject");
        System.out.println(to);

        UserController userController = (UserController) context.getBean("userController");
        System.out.println(userController);

        UserService userService = (UserService)context.getBean("userService");
        System.out.println(userService);

        UserRepository userRepository = (UserRepository) context.getBean("userRepository");
        System.out.println(userRepository);
        //输出
        一月 17, 2020 4:08:16 下午 org.springframework.context.support.ClassPathXmlApplicationContext prepareRefresh
信息: Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@799f7e29: startup date [Fri Jan 17 16:08:16 CST 2020]; root of context hierarchy
一月 17, 2020 4:08:16 下午 org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
信息: Loading XML bean definitions from class path resource [beans-annotation.xml]
Exception in thread "main" org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 'testObject' available
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBeanDefinition(DefaultListableBeanFactory.java:687)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getMergedLocalBeanDefinition(AbstractBeanFactory.java:1207)
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:284)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:197)
    at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:1078)
    at com.cloud.spring.beans.annotation.Main.main(Main.java:19)

assignable

1.exclude

        ApplicationContext context = new ClassPathXmlApplicationContext("beans-annotation.xml");

        TestObject to = (TestObject) context.getBean("testObject");
        System.out.println(to);

        UserController userController = (UserController) context.getBean("userController");
        System.out.println(userController);

        UserService userService = (UserService)context.getBean("userService");
        System.out.println(userService);

        UserRepository userRepository = (UserRepository) context.getBean("userRepository");
        System.out.println(userRepository);
     <context:component-scan base-package="com.cloud.spring.beans.annotation">
        <context:exclude-filter type="assignable" expression="com.cloud.spring.beans.annotation.repository.UserRepository"/>
    </context:component-scan>
//输出
一月 17, 2020 5:17:49 下午 org.springframework.context.support.ClassPathXmlApplicationContext prepareRefresh
信息: Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@799f7e29: startup date [Fri Jan 17 17:17:49 CST 2020]; root of context hierarchy
一月 17, 2020 5:17:50 下午 org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
信息: Loading XML bean definitions from class path resource [beans-annotation.xml]
Exception in thread "main" org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 'userRepository' available
com.cloud.spring.beans.annotation.TestObject@4fb64261
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBeanDefinition(DefaultListableBeanFactory.java:687)
com.cloud.spring.beans.annotation.controller.UserController@42607a4f
    at org.springframework.beans.factory.support.AbstractBeanFactory.getMergedLocalBeanDefinition(AbstractBeanFactory.java:1207)
com.cloud.spring.beans.annotation.service.UserService@782663d3
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:284)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:197)
    at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:1078)
    at com.cloud.spring.beans.annotation.Main.main(Main.java:28)

2.include

    <context:component-scan base-package="com.cloud.spring.beans.annotation" use-default-filters="false">
        <context:include-filter type="assignable" expression="com.cloud.spring.beans.annotation.repository.UserRepository"/>
    </context:component-scan>
    
        ApplicationContext context = new ClassPathXmlApplicationContext("beans-annotation.xml");

//        TestObject to = (TestObject) context.getBean("testObject");
//        System.out.println(to);
//
//        UserController userController = (UserController) context.getBean("userController");
//        System.out.println(userController);
//
//        UserService userService = (UserService)context.getBean("userService");
//        System.out.println(userService);

        UserRepository userRepository = (UserRepository) context.getBean("userRepository");
        System.out.println(userRepository);
//输出
一月 17, 2020 5:43:31 下午 org.springframework.context.support.ClassPathXmlApplicationContext prepareRefresh
信息: Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@799f7e29: startup date [Fri Jan 17 17:43:31 CST 2020]; root of context hierarchy
一月 17, 2020 5:43:31 下午 org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
信息: Loading XML bean definitions from class path resource [beans-annotation.xml]
com.cloud.spring.beans.annotation.repository.UserRepositoryImpl@396e2f39

相关文章

网友评论

    本文标题:Java Spring-通过注解配置Bean

    本文链接:https://www.haomeiwen.com/subject/ebqhzctx.html