[Spring] 基于注解来配置Bean
2017-09-06 12:57
756 查看
Bean的配置方式
基于XML文件的方式基于注解的方式(基于注解配置Bean,基于注解来装配Bean的属性)
在classpath中扫描组件
组件扫描:Spring能够从classpath下自动扫描、侦测和实例化具有特定注解的组件特定组件包括:
@component:基本注解,标识了一个受Spring管理的组件
@Respositoy:标识持久层组件
@Service:标识服务层组件
@Controller:标识表现层组件
对于扫描到的组件,Spring有默认的命名规则,使用非限定类名,第一个字母小写,也可以在注解中通过value属性标识组件的名称
当在组件类中使用了特定的注解后,还需要在Spring的配置文件中声明
<context:component-scan>:
TestObject.java
package com.glemontree.spring.annotation; import org.springframework.stereotype.Component; @Component public class TestObject { }
UserController.java
package com.glemontree.spring.annotation.controller; import org.springframework.stereotype.Controller; @Controller public class UserController { public void execute() { System.out.println("UserController execute..."); } }
UserRepository.java UserRepositoryImpl.java
package com.glemontree.spring.annotation.repository; public interface UserRepository { void save(); }
package com.glemontree.spring.annotation.repository; import org.springframework.stereotype.Repository; @Repository("userRepository") public class UserRepositoryImpl implements UserRepository { public void save() { // TODO Auto-generated method stub System.out.println("UserRepository Save..."); } }
UserService.java
package com.glemontree.spring.annotation.sevice; import org.springframework.stereotype.Service; @Service public class UserService { public void add() { System.out.println("UserService add..."); } }
配置文件:
<?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-4.0.xsd"> <!--扫描com.glemontree.spring.annotation包及其子包--> <context:component-scan base-package="com.glemontree.spring.annotation"> </context:component-scan> </beans>
测试方法
package com.glemontree.spring.annotation; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; import com.glemontree.spring.annotation.controller.UserController; import com.glemontree.spring.annotation.repository.UserRepository; import com.glemontree.spring.annotation.sevice.UserService; public class Main { public static void main(String[] args) { ApplicationContext ctx = new ClassPathXmlApplicationContext("beans-annotation.xml"); TestObject to = (TestObject) ctx.getBean("testObject"); System.out.println(to); UserController uc = (UserController) ctx.getBean("userController"); System.out.println(uc); UserService us = (UserService) ctx.getBean("userService"); System.out.println(us); UserRepository ur = (UserRepository) ctx.getBean("userRepository"); System.out.println(ur); } }
解析:
base-package:指定一个需要扫描的基类包,Spring将会扫描这个基类包里极其子包里的所有类
当需要扫描多个包时,可以使用逗号分隔
如果仅希望扫描特定的类而非基包下的所有类,可使用resource-pattern属性过滤特定的类:
<!--可以通过resource-pattern指定扫描的资源--> <context:component-scan base-package="com.glemontree.spring.beans" resource-pattern:"autowire/*.class"/>
<context:include-filter>子结点表示包含哪些指定表达式的组件,该子结点需要use-default-filter配合使用,即设置
<context:component-scan>的use-default-filter属性为false;
<?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-4.0.xsd"> <context:component-scan base-package="com.glemontree.spring.annotation" use-default-filters="false"> <context:include-filter type="annotation" expression="org.springframework.stereotype.Repository"/> </context:component-scan> </beans>
<context:exclude-filter>子结点表示排除哪些指定表达式的组件;
<?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-4.0.xsd"> <context:component-scan base-package="com.glemontree.spring.annotation"> <!--不包含标注了@Repository的类--> <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Repository"/> </context:component-scan> </beans>
<context:component-scan>下可以包含多个
<context:include-filter>和
<context:exclude-filter>子结点
<context:include-filter>和
<context:exclude-filter>子结点支持多种类型的过滤表达式,常用的有:
annotation:所有标注了xxxAnnotation的类
<?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-4.0.xsd"> <context:component-scan base-package="com.glemontree.spring.annotation"> <!--不包含标注了@Repository的类--> <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Repository"/> </context:component-scan> </beans>
assinable:所有继承或扩展xxxService的类
<?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-4.0.xsd"> <!-- <context:component-scan base-package="com.glemontree.spring.annotation" use-default-filters="false"> <context:include-filter type="annotation" expression="org.springframework.stereotype.Repository"/> </context:component-scan> --> <context:component-scan base-package="com.glemontree.spring.annotation" use-default-filters="true"> <!--排除所有UserRepository和继承自UserRepository的类--> <context:exclude-filter type="assignable" expression="com.glemontree.spring.annotation.repository.UserRepository"/> </context:component-scan> </beans>
<?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-4.0.xsd"> <!-- <context:component-scan base-package="com.glemontree.spring.annotation" use-default-filters="false"> <context:include-filter type="annotation" expression="org.springframework.stereotype.Repository"/> </context:component-scan> --> <context:component-scan base-package="com.glemontree.spring.annotation" use-default-filters="false"> <context:include-filter type="assignable" expression="com.glemontree.spring.annotation.repository.UserRepository"/> </context:component-scan> </beans>
组件装配
<context:component-scan>元素还会自动注册AutowiredAnnotationBeanPostProcessor实例,该实例可以自动装配具有@Autowired和@Resource、@Inject注解的属性。
Autowired:可以自动装配具有兼容类型的单个Bean属性
构造器、普通字段(即使是非public)以及一切具有参数的方法都可以应用@Autowired注解
默认情况下,所有使用@Autowired注解的属性都要被设置,当Spring找不到匹配的Bean装配属性时,会抛出异常,若某一属性允许不被设置,可以设置@Autowired注解的required属性为false
默认情况下,当IOC容器里存在多个类型兼容Bean时,通过类型的自动装配将无法工作,此时可以在@Qualifier注解里提供Bean的名称,Spring允许对方法的入参标注@Qualifier以指定注入Bean的名称:
package com.glemontree.spring.annotation.sevice; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.stereotype.Service; import com.glemontree.spring.annotation.repository.UserRepository; @Service public class UserService { private UserRepository userRepository; @Autowired @Qualifier("userRepositoryImpl") // 通过@Qualifier指定Bean的名称,注意是bean的名称而不是类的名称 public void setUserRepository(UserRepository userRepository) { this.userRepository = userRepository; } public void add() { System.out.println("UserService add..."); userRepository.save(); } }
另外一种写法如下:
package com.glemontree.spring.annotation.sevice; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.stereotype.Service; import com.glemontree.spring.annotation.repository.UserRepository; @Service public class UserService { private UserRepository userRepository; // 将@Qualifier写在入参的前面 @Autowired public void setUserRepository(@Qualifier("userRepositoryImpl")UserRepository userRepository) { this.userRepository = userRepository; } public void add() { System.out.println("UserService add..."); userRepository.save(); } }
泛型依赖注入
BaseRepository.javapackage com.glemontree.spring.generic.di; public class BaseRepository<T> { }
BaseService.java
package com.glemontree.spring.generic.di; import org.springframework.beans.factory.annotation.Autowired; public class BaseService<T> { // BaseService依赖于BaseRepository,通过@Autowired建立关系 @Autowired protected BaseRepository<T> repository; public void add() { System.out.println("add..."); System.out.println(repository); } }
User.java
package com.glemontree.spring.generic.di; public class User { }
UserRepositpry.java
package com.glemontree.spring.generic.di; import org.springframework.stereotype.Repository; // 通过@Repository注解注册bean @Repository public class UserRepository extends BaseRepository<User>{ }
UserService.java
package com.glemontree.spring.generic.di; import org.springframework.stereotype.Service; // 通过@Service注解注册bean @Service public class UserService extends BaseService<User>{ }
beans-generic-di.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-4.0.xsd"> // 通过下面这段话UserRepository和UserService两个bean会被注册 <context:component-scan base-package="com.glemontree.spring.generic.di"></context:component-scan> </beans>
虽然UserService和UserRepository之间并没有建立直接的联系,但是两个泛型类
BaseService<T>和
BaseRepository<T>之间通过
@Autowired建立了联系,因此它们的两个子类UserService和UserRepository也建立了联系。
相关文章推荐
- 【Java.Spring.Core】【IoC】基于注解的Bean装配(非XML配置)
- 【第十二章】零配置 之 12.3 注解实现Bean定义、12.4基于Java类定义Bean配置元数据 ——跟我学spring3
- spring知识四------基于注解的配置bean
- Spring-基于注解的配置[01定义Bean+扫描Bean]
- 框架 day36 Spring3 入门,DI依赖注入,装配bean基于xml/注解, 整合Junit4,配置约束自动提示
- Spring(二)基于注解的方式配置Bean
- Spring-基于注解的配置[02自动装载bean]
- 【Spring】IOC之基于注解的配置bean(上)
- Spring基于注解的方式配置bean的实例
- Spring学习(14)--- 基于Java类的配置Bean 之 @ImportResource & @Value 注解
- Spring-基于注解的配置[03Bean作用范围和生命周期方法]
- Spring学习(15)--- 基于Java类的配置Bean 之 @Bean & @Scope 注解
- Spring学习(13)--- 基于Java类的配置Bean 之 @Configuration & @Bean注解
- [Spring]基于注解的形式配置Bean
- Spring笔记2-基于注解的方式配置Bean
- Spring基于注解配置Bean
- Spring中Bean的配置:基于注解的方式
- Spring_基于注解的方式配置bean
- Spring学习03 基于注解配置Bean
- spring(三)(基于注解的方式配置bean)