(12)Spring学习记录---Spring_bean(Spring_通过注解配置 Bean)

用注解标识特定的组件,用组件扫描让系统自动找到特点的组件 

 

 实例:

1.创建4个包 

(1)annotation

      TestObject.java

import org.springframework.stereotype.Component;

@Component
public class TestObject {

}

Main.java

public class Main {
	public static void main(String[] args) {
		ApplicationContext act=new ClassPathXmlApplicationContext("bean-annotation.xml");
		
//		TestObject testObject=(TestObject) act.getBean("testObject");
//		System.out.println(testObject);
//		
//		UserService userService =(UserService) act.getBean("userService");
//		System.out.println(userService);
//		
//		UserController userController=(UserController)act.getBean("userController");
//		System.out.println(userController);
		
		UserRepository userRepository=(UserRepository)act.getBean("userRepository");
		System.out.println(userRepository);
		
	}
}

(2)annotation.controller

UserController.java

import org.springframework.stereotype.Controller;

@Controller
public class UserController {
	
	
	public void execute() {
		System.out.println("UserController execute...");
	}
}	

(3)annotation.repository

UserRepository.java

public interface UserRepository {
	void save();
}

UserRepositoryImpl.java 

import org.springframework.stereotype.Repository;

@Repository(value="userRepository")
public class UserRepositoryImpl implements UserRepository {

	@Override
	public void save() {
		System.out.println("UserRepositoryImpl save...");
	}

}

(4)annotation.service

UserService.java

import org.springframework.stereotype.Service;

@Service
public class UserService {
	public void add() {
		System.out.println("UserService add...");
	}
}

2.配置xml

<context:component-scan base-package="jjh.test.annotation"/>

3.运行结果

classpath扫描组件有两种方式过滤组件

1.context:include-filter 包含某种组件,该子节点必须满足use-default-filters=false

2.conext:exclude-filter 排除某种组件

type一下集中表达式,常用前两种

1.annotation 组件的全类名

如:org.springframework.stereotype.Repository;

org.springframework.stereotype.Service;

org.springframework.stereotype.Controller;

org.springframework.stereotype.Component;

2.assinable 包含类的全类名

组件装配 

使用@Autowired 自动装配Bean

在UserController.java

下创建UserService并且给它打上注解@Autowired

@Controller
public class UserController {
	
	@Autowired
	private UserService userService;
	
	public void execute() {
		System.out.println("UserController execute...");
		userService.add();
	}
}	

在UserService.java

下创建UserRepository并且给它打上注解@Autowired

系统自动创建UserService和UserRepository的bean

@Service
public class UserService {
	
	@Autowired
	private UserRepository userRepository;
	

	public void add() {
		System.out.println("UserService add...");
		userRepository.save();
	}
}

创建Main方法运行 


public class Main {
	public static void main(String[] args) {
		ApplicationContext act=new ClassPathXmlApplicationContext("bean-annotation.xml");
		
//		TestObject testObject=(TestObject) act.getBean("testObject");
//		System.out.println(testObject);
//		
//		UserService userService =(UserService) act.getBean("userService");
//		userService.add();
//		
		UserController userController=(UserController)act.getBean("userController");
		userController.execute();
//		
//		UserRepository userRepository=(UserRepository)act.getBean("userRepository");
//		System.out.println(userRepository);
		
	}
}

运行结果

@Autowired也可以放在setter方法上

细节问题:

1.在上面的实例中,我在包下都有这些bean,如果没有呢

加入我将UserController.java的@Controller去掉,也就是消除这个组件

结果就是系统找不到这个bean,抛出异常

2.如果我有多个bean呢

比如我有两个类都是继承同一个接口并且标上注解,在其他的类中我通过接口创建实例,则会抛出异常,因为系统不知道你要用的是哪个bean(不知道创建哪个bean 的实例)

默认情况下:

推荐将@Autowired标注在setter方法上,因为系统可以根据实例名去找与其匹配的名

如我创建两个类

1.UserJdbcRepositoryImpl .class

@Repository("userRepository2")
public class UserJdbcRepositoryImpl implements UserRepository {
	@Override
	public void save() {
		System.out.println("UserJdbcRepositoryImpl save...");
	}

}

2.UserRepositoryImpl  .class


@Repository("userRepository")
public class UserRepositoryImpl implements UserRepository {

	@Override
	public void save() {
		System.out.println("UserRepositoryImpl save...");
	}

}

两个类都在注解处取了别名

那么系统就会根据你setter中设置的形参来匹配名字比如

这里的形参名为userRepository2所有系统匹配UserJdbcRepositoryImpl

另一种方法是用@Qualifier指定,直接指定要用的bean

还有一种写法,将@Qualifier(name)加在参数名之前

猜你喜欢

转载自blog.csdn.net/ck784101777/article/details/83098503