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