Spring入门学习(基于注解的方式配置Bean) 第十二节

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/u011171125/article/details/85719509

Spring入门学习(基于注解的方式配置Bean)

指定SpringIOC容器扫描包

在这里插入图片描述

分别创建repository,service,controller

  1. 添加类TestObject,使用@Component注解标注为组件:
    @Component
    public class TestObject {
    	
    }
    
  2. 创建repository层相关类:
    public interface UserRepository {
    	void save();
    }
    
    UserRepositoryImpl实现UserRepository接口,并在类上添加注解@Repository
    @Repository
    public class UserRepositoryImpl implements UserRepository {
    
    	@Autowired(required=false)
    	private TestObject testObject;
    	
    	@Override
    	public void save() {
    		System.out.println("UserRepositoryImpl Save...");
    		System.out.println(testObject);
    	}
    }
    
  3. 创建service层相关类,并在类上添加@Service注解:
    @Service
    public class UserService {
    
    	private UserRepository userRepository;
    	
    	@Autowired
    	public void setUserRepository(UserRepository userRepository) {
    		this.userRepository = userRepository;
    	}
    
    	public void add(){
    		System.out.println("UserService add...");
    		userRepository.save();
    	}
    }
    
  4. 创建controller层,添加注解@Controller:
    @Controller
    public class UserController {
    	
    	@Autowired
    	private UserService userService;
    
    	public void execute() {
    		System.out.println("UserController execute...");
    		userService.add();
    	}
    }
    
  5. 创建
    <!-- 指定SpringIOC容器扫描的包 -->
    <!-- 可以通过resource-pattern指定扫描的资源 -->
    <context:component-scan 
    	base-package="com.fafa.spring.bean.annotation"></context:component-scan>
    
  6. 新建测试类:
    public class Main {
    
    	public static void main(String[] args) {
    		ApplicationContext ctx = new ClassPathXmlApplicationContext("classpath*:beans-annotation.xml");
    		
    		TestObject to = (TestObject)ctx.getBean("testObject");
    		System.out.println(to);
    		
    		UserController userController = (UserController) ctx.getBean("userController");
    		System.out.println(userController);
    		// userController.execute();
    		
    		UserService userService = (UserService) ctx.getBean("userService");
    		System.out.println(userService);
    		
    		UserRepository userRepository = (UserRepository) ctx.getBean("userRepositoryImpl");
    		System.out.println(userRepository);
    	}
    }
    
    测试结果:
    com.fafa.spring.bean.annotation.TestObject@b8be647
    com.fafa.spring.bean.annotation.service.UserController@dbb453d
    com.fafa.spring.bean.annotation.controller.UserService@1beaed6
    com.fafa.spring.bean.annotation.repository.UserRepositoryImpl@dc8647f
    
  7. 如果此时使用resource-pattern指定扫描的类,则容器中就只会有指定的扫描的bean
    <context:component-scan 
    	base-package="com.fafa.spring.bean.annotation"
    	resource-pattern="repository/*.class"></context:component-scan>
    
  8. 如果要注入的bean可能不存在的时候可以使用@Autowired(required=false)指定不是必须的
    注释掉TestObject类中的@Component,将UserRepositoryImplTestObject的注解设置为@Autowired(required=false)测试:
    	public static void main(String[] args) {
    		ApplicationContext ctx = new ClassPathXmlApplicationContext("classpath*:beans-annotation.xml");
    		
    		UserRepository userRepository = (UserRepository) ctx.getBean("userRepositoryImpl");
    		userRepository.save();
    		System.out.println(userRepository);
    	}
    
    测试结果:testObject为null
    UserRepositoryImpl Save...
    null
    com.fafa.spring.bean.annotation.repository.UserRepositoryImpl@7af2a691
    
    该方式避免了在使用的bean时候发生bean找不到的错误。
  9. 再新建一个UserJdbcRepositoryImpl.java实现UserRepository接口,添加@Repository注解:
    @Repository
    public class UserJdbcRepositoryImpl implements UserRepository {
    	@Override
    	public void save() {
    		System.out.println("UserJdbcRepository save。。。。。");
    	}
    
    }
    
  10. 此时在通过UserRepository接口调用方法的时候,会报bean不唯一的错:
    public class Main {
    
    	public static void main(String[] args) {
    		ApplicationContext ctx = new ClassPathXmlApplicationContext("classpath*:beans-annotation.xml");
    		 
    		UserController userController = (UserController) ctx.getBean("userController");
    		System.out.println(userController);
    		userController.execute();
    	}
    }
    
    错误信息:
    No qualifying bean of type [com.fafa.spring.bean.annotation.repository.UserRepository] is defined: expected single matching bean but found 2: userJdbcRepositoryImpl,userRepositoryImpl
    
    要解决这个问题,可以使用@Qualifier注解指定调用接口对应的bean名称,如UserSerive中:
    @Service
    public class UserService {
    
    	private UserRepository userRepository;
    	
    	@Autowired
    	public void setUserRepository(@Qualifier("userJdbcRepositoryImpl") UserRepository userRepository) {
    		this.userRepository = userRepository;
    	}
    
    	public void add(){
    		System.out.println("UserService add...");
    		userRepository.save();
    	}
    }
    
    使用@Qualifier("userJdbcRepositoryImpl")标注使用UserJdbcRepositoryImpl类中的方法:
    com.fafa.spring.bean.annotation.service.UserController@7dcf7147
    UserController execute...
    UserService add...
    UserJdbcRepository save。。。。。
    
  11. 此外还可以使用context:exclude-filtercontext:include-filter来指定在包扫描时要包含的包或要排除的包,以及使用use-default-filters="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.1.xsd">
    	
    	<!-- 指定SpringIOC容器扫描的包 -->
    	<!-- 可以通过resource-pattern指定扫描的资源 -->
    	<!-- <context:component-scan 
    		base-package="com.fafa.spring.bean.annotation"
    		resource-pattern="repository/*.class"></context:component-scan> -->
    		
    	<!-- context:exclude-filter 子节点指定排除哪些指定表达式的组件 -->
    	<!-- 
    		context:include-filter 子节点指定包含哪些指定表达式的组件,该子节点需要use-default-filters 配合使用
    		use-default-filters: 默认的filter是会全部扫描组件的,设为false后就只会使用指定的组件
    	 -->
    	<context:component-scan 
    		base-package="com.fafa.spring.bean.annotation">
    		<!-- use-default-filters="false" -->
    		
    		<!-- <context:exclude-filter type="annotation" 
    			expression="org.springframework.stereotype.Repository"/> 
    		
    		
    		<context:include-filter type="annotation" 
    			expression="org.springframework.stereotype.Repository"/> -->
    		
    		
    		<context:exclude-filter type="assignable" 
    			expression="com.fafa.spring.bean.annotation.repository.UserJdbcRepositoryImpl"/>
    		
    		
    		<!-- <context:include-filter type="assignable" 
    			expression="com.fafa.spring.bean.annotation.repository.UserRepositoryImpl"/>  -->
    		
    	</context:component-scan>
    		
    </beans>
    

猜你喜欢

转载自blog.csdn.net/u011171125/article/details/85719509