基于spring-context基本框架的注解开发主要内容如下图
使用在自已写的类上添加@Component完成对该类定义,例子如下:
@Component
public class BookDaoImpl implements BookDao {
//to do something
}
Spring为了更方便大家区分bean的用途在Component下派生出三个子类:
编写完了在xml配置文件中添加一个包扫描即可
<context:component-scan base-package="com.xxx" />
通过编写一个类并用@Configuration方式来指定该类作为配置文件使用,例子如下:
//配置类注解(必填)
@Configuration
//包扫描路径
@ComponentScan("com.hyq")
public class SpringConfig {
}
不同于xml文件方式,spring容器要用AnnotationConfigApplicationContext来实例化,代码如下:
//创建容器
ApplicationContext ctx =new AnnotationConfigApplicationContext(SpringConfig.class);
//获取Bean
BookDao bookDao = ctx.getBean(BookDao.class);
@ComponentScan包扫描只允行出现一次,如果有多个不同路径的包需要扫描可使用数组方式:
@Configuration
//包扫描路径
@ComponentScan({"com.hyq","com.reinfore"})
public class SpringConfig {
}
比如当前我有一个类如下:
public class BookServiceImpl implements BookService {
BookDao bookDao;
public void setUserMapper(BookDao bookDao) {
this.bookDao = bookDao;
}
@Override
public void save() {
bookDao.save();
}
}
使用xml方式我们bean这样写的
<bean id="bookDao" class="com.hyq.springStudy.dao.impl.BookDaoImpl">
<bean id="bookService" class="com.hyq.springStudy.service.impl.BookServiceImpl">
<property name="bookDao" ref="bookDao" />
bean>
使用@Servier注解替换
public class BookServiceImpl implements BookService {
//因Autowired使用暴力反射方式注入,所以不需要提供setter方法
@Autowired
BookDao bookDao;
@Override
public void save() {
bookDao.save();
}
}
@Autowired使用的类型注入,需要有多个相同类型的Bean程序会报错。解决方法是添加多一个@Qualifier注解写明注入Bean的名字。
//BookServiceImpl 类中添加Qualifier注解指定名字
@Autowired
@Qualifier("bookDao1")
BookDao bookDao;
//Dao类的注解中添加名字参数
@Repository("bookDao1")
public class BookDaoImpl implements BookDao {
//to do something
}
对于String、Integer等简单类型的注入直接使用@Value,例子如下:
public class BookServiceImpl implements BookService {
//因Autowired使用暴力反射方式注入,所以不需要提供setter方法
@Autowired
BookDao bookDao;
//直接使用@Value注解写入固定值
@Value("book1")
String bookName;
//使用@Value注解写入配置文件中获取的值
@Value("${book.name}")
String bookName2;
@Override
public void save() {
bookDao.save();
}
}
按上边这样直接写死是很少见的,开发中应该是使用读取配置的方式注入更多使用${xxx}资源占位符读取配置中值进行注入
在添加@Configuration注解的配置类中添加@PropertySource()来加载配置文件。
@Configuration
//包扫描路径
@ComponentScan({"com.hyq","com.reinfore"})
//配置单个文件
@PropertySource("jdbc.properties")
//配置多个文件
//@PropertySource("jdbc.properties","my.properties")
public class SpringConfig {
}
当要使用第三方开发的jar包中资源时我们不可能到别人的源代码上添加注解,spring为解决这问题给出方法是写一个方法返回值为第三方bean的类型再加上@Bean注解,我们这里拿druid数据库连接池为例代码如下:
public class DataSourceBean {
//读取jdbc.properties中的数据库配置注入
@Value("${jdbc.classDriver}")
private String driver;
@Value("${jdbc.url}")
private String url;
@Value("${jdbc.username}")
private String username;
@Value("${jdbc.password}")
private String password;
//返回DruidDataSource的Bean
@Bean
public DataSource getDataSource(){
DruidDataSource ds = new DruidDataSource();
ds.setUrl(url);
ds.setDriverClassName(driver);
ds.setUsername(username);
ds.setPassword(password);
return ds;
}
}
为了避免在主配置类中写一大堆第三方Bean方法导致难以维护和阅读,建议将相同内容的Bean单独抽出一个类来编写,例如上边代码单独编写DataSourceBean
编写DataSourceBean后为了让Spring能知道这个类我们在配置类中添加一个@Import来导入,改造后的配置类如下
@Configuration
//包扫描路径
@ComponentScan({"com.hyq","com.reinfore"})
//配置单个文件
@PropertySource("jdbc.properties")
//配置多个文件
//@PropertySource("jdbc.properties","my.properties")
//添加其它第三方类的导入
@Import(DataSourceBean.class)
public class SpringConfig {
}
另外一种代替@Import的方式
还可以在DataSourceBean类添加@Configuration注解,再通过SpringConfig的@ComponentScan配置包名,让Spring可以扫描到这个包,这样就不用@Import。
但是用这个方式写太多@Configuration会导致后期维护比较难找到主要配置类在哪,所以建议用@Import方式更加直观