首先,注解配置Bean时xml需要在写在context中,所以我们先来配置xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
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.xsd">
<context:component-scan base-package="com.cacb"/>
</beans>
可以看到,与之前的Bean配置的区别为这种方法可以直接设置需要扫描的包,自动扫描包内注解了的Bean,那么下面就看如何注解类,以BookDao距离
package com.cacb.dao.impl;
import com.cacb.dao.BookDao;
import org.springframework.stereotype.Component;
@Component("bookDao")
public class BookDaoImpl implements BookDao {
@Override
public void save() {
System.out.println("BookDao saving!");
}
}
?可以看到,注解的部分为@Component("bookDao"),所以在获取该Bean时可以通过名称来访问
BookDao bookDao = (BookDao)cxt.getBean("bookDao");
那如果在注解时我没有给出名称呢?
package com.cacb.dao.impl;
import com.cacb.dao.BookDao;
import org.springframework.stereotype.Component;
@Component()
public class BookDaoImpl implements BookDao {
@Override
public void save() {
System.out.println("BookDao saving!");
}
}
此时,通过名称来访问显然是不成立的,此时可以用类型来访问
BookDao bookDao = (BookDao)cxt.getBean(BookDao.class);
@Controller:? ? ? ? ?用于表现层Bean定义
@Service:? ? ? ? ? ? ?用于业务层Bean定义
@Respository:?????用于数据层Bean定义
这三个注解方法与@component功能完全一致,只不过方便我们理解
Spring3.0开启了纯注解开发模式,使用java类替代配置文件,开启了Spring快速开发赛道
Java类代替Spring核心配置文件
以我上边用到的例子来演示
这是原来的xml文件
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
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.xsd">
<context:component-scan base-package="com.cacb"/>
</beans>
我们现在需要的是取缔掉书写较为复杂的xml文件,那么用什么代替他呢?
这里我们可以创建一个SpringConfig类来代替它,当然,还要用注解@Configuration来告诉系统这是配置文件,代码示例如下:
package com.cacb.config;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
@Configuration
@ComponentScan("com.cacb")
public class SpringConfig {
}
我们可以看到,代码中的?
@ComponentScan("com.cacb")
与原配置文件中的
<context:component-scan base-package="com.cacb"/>
作用是相同的。
注意事项
@Configuration注解用于设定当前类为配置类
@ComponentScan注解用于设定扫描路径,此注解只能添加一次,多个数据要用数组格式
@ComponetScan({"com.cacb.dao","com.cacb.service"})
为了使用注解来管理Bean的生命周期,我们以BookDao为例来通过注解为Bean的生命周期提供设置,代码如下:
package com.cacb.dao.impl;
import com.cacb.dao.BookDao;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Repository;
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
@Repository
@Component
@Scope("singleton")
public class BookDaoImpl implements BookDao {
@Override
public void save() {
System.out.println("BookDao saving!");
}
@PostConstruct
public void init(){
System.out.println("BookDao init!");
}
@PreDestroy
public void destroy(){
System.out.println("BookDao destroy");
}
}
?
解决了Bean的注解管理,下一步我们要解决的就是依赖注入的注解开发。
以BookDao和BookService为例
@Service
public class BookServiceImpl implements BookService {
@Autowired
BookDao bookDao;
public void save() {
System.out.println("BookService saving!");
bookDao.save();
}
}
可以看到,基本与自动装配的xml文件写法一致,不过是改为了Autowired,?下面是一些注意事项
自动装配基于反射设计创建对象并暴力反射对应属性为私有属性初始化数据,因此无需提供setter方法
自动装配建议使用无参构造方法创建对象(默认),如果不提供对应构造方法,需要提供唯一的构造方法
?但还有另一个问题,如果我们有两个类型相同的Bean需要同时加载呢?
先看解决代码:(假设有bookdao和boodao_这两个类型相同的bean需要注入,这里展示bookdao的注入)
bookdao:
package com.cacb.dao.impl;
import com.cacb.dao.BookDao;
import org.springframework.stereotype.Repository;
@Repository("bookDao")
public class BookDaoImpl implements BookDao {
public void save() {
System.out.println("BookDao saving!");
}
}
bookservice
package com.cacb.service.impl;
import com.cacb.dao.BookDao;
import com.cacb.service.BookService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;
@Service
public class BookServiceImpl implements BookService {
@Autowired
@Qualifier("bookDao")
BookDao bookDao;
public void save() {
System.out.println("BookService saving!");
bookDao.save();
}
}
可以看到,这时我们一定要给bookdao设置名称,然后再Autowired后使用Qualifier("bookDao")来注解,这样就能解决问题。
注意:
@Qualifier注解无法单独使用,必须配合@Autowired注解使用
方法很简单,直接上代码:
@Value("cacb")
private String name;
就是这样,不多赘述。
以jbdc.properties文件的加载为例,文件内容如下:
name=cacb
要引入外部配置文件,我们肯定还是要修改配置类SpringConfig
直接给出注解:
@PropertySource("jbdc.properties")
注
路径仅支持单一文件配置,多文件需要使用数组格式配置,但不允许使用他通配符*?
?那么如果想用jbdc这个外部配置文件的name来对应我们在实现类中写的name呢?
实现方法如下,
@Value(${name})
private String name;
这样就能将外部配置文件的name传入