1. 程式人生 > >(12)Spring學習記錄---Spring_bean(Spring_通過註解配置 Bean)

(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)加在引數名之前