XML配置和注解开发对比理解
IOC注解开发流程
步骤一:定义配置类代替配置文件
@Configuration
@ComponentScan({"com.xixi.dao","com.xixi.service"})
public class SpringConfig{}
步骤二:资源类声明被扫描
@Component
public class BookDaoImpl{
public void save() {
System.out.println("Book dao save...");
}
}
public interface BookDao {
public void save();
}
@Component
public class BookServiceImpl implements BookService {
@Autowired
private BookDao bookDao;
public void save() {
System.out.println("book service save ...");
bookDao.save();
}
public void setBookDao(BookDao bookDao){
this.bookDao=bookDao;
}
}
public interface BookService {
public void save();
}
步骤三:在测试类中加载配置类,获取Bean对象并使用
public class MyTest {
public static void main(String[] args){
//AnnotationConfigApplicationContext加载Spring配置类初始化Spring容器
ApplicationContext ctx = new AnnotationConfigApplicationContext(SpringConfig.class);
BookDao bookDao = (BookDao) ctx.getBean("bookDaoImpl");
bookDao.save();
//按类型获取bean
BookService bookService = ctx.getBean(BookService.class);
bookDao.save();
}
}
注解
被扫描注解 | |
---|---|
@Component注解 | @Controller,@Service,@Respository |
@Component | 未知bean |
@Controller | 控制层 |
@Service | 业务层 |
@Repository | 持久层 |
1)扫描衍生注解
//定义该类为spring配置文件类
@Configuration
@ComponentScan({"com.itgaohe.dao","com.itgaohe.service"})
public class StringConfig {
}
2)作用范围和生命周期注解配置
@Respository注解通常用于标记 DAO(Data Access Object)类,它告诉 Spring 这是一个持久层组件,负责数据访问。通常情况下,@Repository
注解应该标记在数据访问对象(DAO)的实现类上,而不是接口上。
原因:
-
接口与实现分离原则:在面向对象设计中,接口定义了行为,而实现类提供了具体的实现。
@Repository
注解是与具体的数据访问逻辑相关的,而不是接口的定义。因此,将其标记在实现类上更符合设计原则。 -
Spring IoC容器管理:Spring IoC容器需要知道哪些类需要被实例化和管理。标记实现类而不是接口可以确保 Spring 仅将实际的实现类注册为 bean,并为其创建实例,而不会将接口本身注册为 bean。
-
接口的多实现:在某些情况下,可能会有多个实现类实现同一个接口。如果将
@Repository
注解放在接口上,Spring 将无法确定应该选择哪个实现类进行注入。通过将注解放在实现类上,可以明确指定哪个实现类应该被注册为 bean。
@Scope("singleton")是 Spring 框架中的一个注解,用于指定被注解的组件的作用域。在这里,singleton
是作用域的一种类型,表示该组件在 Spring 容器中是单例的,即每次注入或获取该组件时,都会得到同一个实例。
单例模式是一种常见的设计模式,它确保一个类只有一个实例,并提供一个全局访问点。在 Spring 中,当一个 Bean 被声明为 singleton 作用域时,Spring 容器会负责创建该 Bean 的唯一实例,并在之后的每次请求中重复使用这个实例。
@Repository
@Scope("singleton") //作用范围
public class BookDaoImpl implements BookDao {
public BookDaoImpl() {
System.out.println("book dao constructor ...");
}
@PostConstruct // 在构造方法执行后执行
public void init(){
System.out.println("book init ...");
}
@PreDestroy // 在bean销毁的时候执行
public void destroy(){
System.out.println("book destory ...");
}
}
3)依赖注入
@Component
是 Spring 框架中用来表示一个通用的 Spring 管理的组件的注解。当一个类被标记为 @Component
时,Spring 容器会自动扫描并将其注册为一个 Spring bean,从而可以在应用程序中进行依赖注入或其他操作。
除了 @Component
注解外,Spring 还提供了其他几个注解,如 @Controller
、@Service
和 @Repository
,它们分别用于标记 MVC 控制器、业务逻辑服务和数据访问对象(DAO)。这些注解都是 @Component
注解的特殊化,它们提供了更具体的语义,能够更好地描述被标记类的作用和职责。
-
@Controller
用于标记 Spring MVC 控制器类,表示它处理 HTTP 请求和响应。 -
@Service
用于标记业务逻辑服务类,表示它提供了特定的业务功能。 -
@Repository
用于标记数据访问对象(DAO)类,表示它提供了数据访问和持久化的功能。
@Service
public class BookServiceImpl implements BookService {
//@Autowired:注入引用类型,自动装配模式,默认按类型装配
@Autowired
//@Qualifier:自动装配bean时按bean名称装配
@Qualifier("bookDao")
private BookDao bookDao;
public void save() {
System.out.println("book service save ...");
bookDao.save();
}
}
4)注解开发-JDBC集成
//properties 配置文件扫描注入
@PropertySource({"jdbc.properties"})
public class JdbcConfig {
//@Bean:表示当前方法的返回值是一个bean对象,添加到IOC容器中
//方法名就是这个对象的唯一标识
@Bean
public DataSource dataSource(){
DruidDataSource ds = new DruidDataSource();
ds.setDriverClassName("com.mysql.jdbc.Driver");
ds.setUrl("jdbc:mysql://localhost:3306/spring_db");
ds.setUsername("root");
ds.setPassword("123456");
return ds;
}
}
5)注解开发-其他配置类设置
@Import:导入配置信息
@Configuration
@ComponentScan("com.gaohe")
//@Import:导入配置信息
@Import({JdbcConfig.class})
public class SpringConfig {
}
6)注解开发-整合junit单元测试
步骤一:导入依赖
<!--junit-->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
</dependency>
<!--spring整合junit-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>5.2.10.RELEASE</version>
</dependency>
步骤二:使用Spring整合Junit专用的类加载器
//【第二步】使用Spring整合Junit专用的类加载器
@RunWith(SpringJUnit4ClassRunner.class)
//【第三步】加载配置文件或者配置类
@ContextConfiguration(classes = {SpringConfiguration.class}) //加载配置类
public class AccountServiceTest {
//支持自动装配注入bean
@Autowired
private AccountService accountService;
@Test
public void testFindById(){
System.out.println(accountService.findById(1));
}
}