Spring-ioc註解程式設計
這裡的註解是最初級的一些註解,掌握了之後再學習其它的註解
註解掃描
<?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 https://www.springframework.org/schema/context/spring-context.xsd"> <!--此標籤表示開啟註解掃描,即掃描對應包及其子包的註解--> <context:component-scan base-package="com.ty"></context:component-scan> </beans>
除了上述方式還可以指定過濾規則來進行註解掃描
<context:component-scan base-package="com.ty"> <!--排除過濾,排除包中的某些類 type="":指定過濾規則 annotation:按照註解進行排除,標註了指定註解的元件不要,expression表示要過濾的註解 assignable:指定排除某個具體的類,按照類排除,expression表示不註冊的具體類名 aspectj:後面講aop的時候說明要使用的aspectj表示式,不用 custom:定義一個typeFilter,自己寫程式碼決定哪些類被過濾掉,不用 regex:使用正則表示式過濾,不用 --> <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/> </context:component-scan>
<!--包含過濾,指定包中的類
需要先配置use-default-filters屬性,讓預設掃描方式失效,預設是掃描全部
剩下的過濾屬性跟排除過濾相同
-->
<context:component-scan base-package="com.ty" use-default-filters="false">
<context:include-filter type="aspectj" expression="com.ty.other.*"/>
</context:component-scan>
建立物件
@Component
此註解就是原配置方式中的<bean>標籤,即:<bean id="user" class="com.ty.bean.User">
註解中元件的id預設是類名首字母小寫,class就是底層通過反射獲取User類資訊;通過@Component分別又衍生出三個註解
@Controller:控制器,推薦給controller層新增此註解
@Service:業務邏輯,推薦給業務邏輯層新增此註解
@Repository:倉庫管理,推薦給資料訪問層新增此註解
這4個註解產生的效果方式是相同的,只是為了方便閱讀,提高可讀性
@Component
public class User {
private String username;
private String password;
/*省略構造,getter/setter和toString方法 */
}
@Scope
設定bean物件的作用域,就是bean標籤中的scope屬性
@Lazy
延遲建立單例項物件,就是bean標籤中的lazy="false"屬性
@PostConstruct
@PreDestroy
這兩個註解表示bean物件的物件的生命週期,就是bean標籤中的init-method和destroy-method屬性
@PostConstruct
public void init() {
System.out.println("init");
}
@PreDestroy
public void destroy() {
System.out.println("destroy");
}
依賴注入
@Autowired
@Repository
public class UserDaoImpl implements UserDao {
@Override
public void findUser() {
System.out.println("查詢使用者!");
}
}
@Service
public class UserServiceImpl implements UserService {
@Autowired
private UserDao userDao;
@Override
public void login() {
userDao.findUser();
}
}
注意:此註解預設是按照型別進行自動裝配(就是注入)
1、如果只找到一個,則直接進行賦值,
2、如果沒有找到,則直接丟擲異常,
3、如果找到多個,那麼會按照變數名作為id繼續匹配,
1、匹配上直接進行裝配
2、如果匹配不上則直接報異常
@Service
public class UserServiceImpl implements UserService {
@Autowired
private UserDao userDao2;
@Override
public void login() {
userDao2.findUser();
}
}
//UserServiceImpl2繼承UserServiceImpl類
@Service
public class UserServiceImpl2 extends UserServiceImpl {
@Autowired
private UserDao userDao;
@Override
public void login() {
System.out.println("UserServiceImpl2");
userDao.findUser();
}
}
@Controller
public class UserController {
@Autowired
private UserService userServiceImpl;
public void test() {
userServiceImpl.login();
}
}
方法上也可以有@Autowired註解
@Autowired
public void setUserService(UserService userServiceImpl) {
this.userService = userServiceImpl;
}
@Qualifier
此註解配套@Autowired使用,用來指定id的名字,讓其按照名字裝配;按照名字找到了就進行裝配,否則就報錯
@Controller
public class UserController {
@Autowired
@Qualifier("userServiceImpl")
private UserService userService;
public void test() {
userService.login();
}
}
@Autowired註解可以用在方法上,@Qualifier只可以用在引數列表中
@Autowired
public void test(@Qualifier("userServiceImpl2") UserService userService) {
System.out.println("此方法被呼叫:" + userService);
}
ps:方法上有@AutoWired註解時:bean建立時會自動呼叫,這個方法的每個引數都會自動注入
@Qualifier註解作用在引數上時,指定屬性的id名字
@Resource
@Resource註解的作用和@Autowired的作用相同,而且@Resource(name="") = @Autowired+@Resource
public class UserController {
@Resource(name = "userServiceImpl")
private UserService userService;
}
等同於:
public class UserController {
@Autowired
@Qualifier("userServiceImpl")
private UserService userService;
}
兩者的功能相同,但還是有區別的:
@Autowired註解是Spring提供的,而@Resource是JavaEE規範提供的
@Autowired註解預設按照型別裝配,而@Resource註解預設是按照名字裝配
@Value
屬性賦值,這種方式不能用在靜態變數上,而且不能注入集合型別
#先定義一個properties屬性檔案,並設定要注入屬性的值
username=jack
password=root
<!--把剛剛定義好的properties屬性檔案載入到配置檔案中-->
<context:property-placeholder location="classpath:bean.properties"></context:property-placeholder>
或者在類上新增@PropertySource("bean.properties")註解
//在屬性上加 @Value("${key}") 註解
@Value("${username}")
private String username;
@Value("${password}")
private String password;
最後再看一下泛型依賴
泛型依賴
public class Student {
}
public class Teacher {
}
public interface BaseDao<T> {
void save();
}
//StudentDao.java
@Repository
public class StudentDao implements BaseDao<Student> {
@Override
public void save() {
System.out.println("儲存學生!");
}
}
//TeacherDao.java
@Repository
public class TeacherDao implements BaseDao<Teacher> {
@Override
public void save() {
System.out.println("儲存老師!");
}
}
public class BaseService<T> {
@Autowired
private BaseDao<T> baseDao;
public void save(){
baseDao.save();
}
}
//StudentService.java
@Service
public class StudentService extends BaseService<Student> {
}
//TeacherService.java
@Service
public class TeacherService extends BaseService<Teacher> {
}
//測試
ApplicationContext context=new ClassPathXmlApplicationContext("applicationContext.xml");
StudentService studentService = context.getBean("studentService", StudentService.class);
TeacherService teacherService = context.getBean("teacherService", TeacherService.class);
studentService.save();
teacherService.save();