您的位置:首页 > 编程语言 > Java开发

[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.java

package 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也建立了联系。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  spring 注解 bean