Spring 框架核心组件之一是 IOC,IOC 则管理 Bean 的创建和 Bean 之间的依赖注入,对于 Bean 的创建可以通过在 XML 里面使用标签来配置,对于 Bean 之间的依赖可以使用构造方法注入、Set 方法注入在 XML 里面配置。使用这种方式会使XML(但各个组件(类、属性)之间的关系、依赖比较清晰,哪些需要注解、哪些不需要) 变的比较臃肿庞大,并且还需要开发人员一个个的在 XML 里面配置 Bean 之间的依赖,这简直是一个灾难。
还好 Spring 框架给我们提供了一系列的注解(但必须到源码那里,才知道哪些用到了注解、类里面又有哪些依赖注入,优点:开发方便)让开发人员从这个灾难中解脱出来,比如在一个类的成员变量上标注了一个简单的@Autowired 注解就可以实现了 Bean 之间的自动依赖注入,在一个类上标注了一个简单的@Component 注解就可以让一个 Bean 注入到 Spring 容器………而 Spring 框架是如何通过注解简化我们的工作量,实现这些功能的。
<?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
http://www.springframework.org/schema/context/spring-context-4.0.xsd
">
<!-- 扫描包含注解定义的类包-->
<!--base-package的值是类的包名:这样就可以在该包下的所有类和属性都可以用注解了 -->
<!--如果这样写:<context:component-scan base-package="net.deniro.spring4"
resource-pattern="anno/*.class"/>
表示:默认情况下 resource-pattern 属性的值为 **./*.class,
即基类包里所有的类 。 上面的设置,让它仅扫描基类包中的 anno 子包下的类。 -->
<context:component-scan base-package="net.deniro.spring4"/>
</beans>
2.pom.xml
<dependencies>
<!-- https://mvnrepository.com/artifact/junit/junit -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.0</version>
<scope>test</scope>
</dependency>
<!-- spring bean -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
<version>4.0.0.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>4.0.0.RELEASE</version>
</dependency>
</dependencies>
3.java
//@service(Service层)、@Controller(web层)、@Repository(Dao层)
//作用都是定义在类上,加入到ApplicationContext.xml容器中
@Service("UserServiceImpl")
// 相当于在ApplicationContext.xml中加入<bean name = "UserServiceImpl" class = "net.deniro.spring4.UserServiceImpl"
public class UserServiceImpl {
// name 是 定义在 UserDaoImpl 上面的 @Service("UserDao")
@Resuorce(name="UserDao")
// 因为已经在UserDaoImpl类上面声明了@Repository("UserDao") ,
//所以这样就相当于 UserDao userDao = new UserDaoImpl();
private UserDao userDao;
@Value(value="王东")
// 赋予默认值
String name;
public void addUser() {
userDao.addUser();
}
@Autowired
// 同Resuorce一样进行自动装配,但可以设置name="bookDao2",可以指定名称
public void setUserDao(@Qualifier("userDao")UserDao userDao) {
System.out.println("进去了set");
this.userDao = userDao;
}
public UserDao getUserDao() {
return userDao;
}
}
- Main
public class Demo {
@Test
public void First() {
ApplicationContext context = new ClassPathXmlApplicationContext("AplicationContext.xml");
UserService show=(UserService) context.getBean("UserServiceImpl");
UserService.setUserDao();
}
}
【两种处理策略】
(1)类级别的注解:如@Component、@Repository、@Controller、@Service以及JavaEE6的@ManagedBean和@Named注解,都是添加在类上面的类级别注解。
Spring容器根据注解的过滤规则扫描读取注解Bean定义类,并将其注册到Spring IoC容器中。
(2)类内部的注解:如@Autowire、@Value、@Resource以及EJB和WebService相关的注解等,都是添加在类内部的字段或者方法上的类内部注解。