使用注解配置
步骤
- 导包(4+2+1)
基本4个组件包加2个日志包(log4j,logging),再加aop
- 将对象注册到容器中
spring 中提供@Component 的三个衍生注解:(功能目前来讲是一致的)
如果不指定任何属性时,默认使用短类名作为bean的id(首字母改成小写)
@Component("user")
@Service("user") //业务层service层对象
@Controller("user") //Web层对象
@Repository("user") //持久层dao层对象
这三个注解是为了让标注类本身的用途清析
- 指定对象的作用范围(==单例还是多例==)
@Scope("prototype")
- 依赖注入(使用注解注入的方式, 可以不用提供 set 方法)
@Value :用于注入普通类型. @Autowired :自动装配:
- 默认按类型进行装配.
- 按名称注入:
- @Qualifier:强制使用名称注入. @Resource 相当于:
- @Autowired 和@Qualifier 一起使用.
@AutoWired默认按类型装配(而且这个注解是属于Spring的).默认情况下依赖的对象必须存在.如果要允许null值,可以设置它的required属性为false @Autowired(required=false) ,如果我们想使用名称装配可以结合@Qualifier注解进行使用
@Autowired()
@Qualifier("baseDao")
private BaseDao baseDao;
@Resource默认按照名称进行装配.该名称可以通过注解中name属性进行指定.如果没有指定name属性,当注解写在字段上时,默认取字段名,按照名称查找,如果注解写在setter方法上默认取属性名进行装配。当找不到与名称匹配的bean时才按照类型进行装配。但是需要注意的是,如果name属性一旦指定,就只会按照名称进行装配。
如果接口有多个实现类,我们需要指定要注入的哪个实现类
@Resource(name = "manImpl")//注意是manImpl不是ManImpl,因为使用@Service,容器为我们创建bean时默认类名首字母小写
private Human human;
@Autowired
@Qualifier("manImpl")
private Human human;
Spring属于第三方的,J2EE是Java自己的东西。使用@Resource可以减少代码和Spring之间的耦合.
- 值类型注入
通过反射的field赋值,破坏了封装性.不推荐使用
@Value("tom")
private String name;
@Value("18")
private Integer age;
通过set方法赋值(推荐使用)
@Value("tom")
public void setName(String name) {
this.name = name;
}
- 引用类型注入
使用@Autowired(自动装配),会帮我们自动查找该类型的对象,并赋值.@Qulifier通常与Autowired一起使用.可以指定容器中的哪一个对象,赋值给引用类型的属性
@Component("user")
public class User {
private String name;
@Value("18")
private Integer age;
//@Resource(name="car")
@Autowired
@Qualifier("car2")
private Car car;
@AutoWired:
作用:如果spring容器中同一个类型有多个bean存在,则需要根据变量名称和bean的id进行比较。如果有相同则能注入成功;否则注入失败。
@Autowired 在方法上的时候.当项目启动,加载web.xml时.springIOC容器创建 会扫描指定的包下的所有注解.当扫描的时候会实例所有被加载的类,类中方法上有@autowired的注解时,会调用这个方法.
@Repository
public class PersonDaoImpl extends HibernateDaoSupport implements PersonDao {
//@Autowired
//private HibernateTemplate hibernateTemplate;
//@Autowired // 私有成员变量的注入
//private SessionFactory sessionFactory;
/*
* 1. tomcat启动,加载自身web.xml
* 2. 加载所有项目的web.xml
* 3. 创建Spring的IOC容器
* 4. 扫描所有的cn.itcast包, 扫描@Repository、@Autowired
* 5. 当前扫描到@Autowired时候,会根据方法参数的类型,去容器找该类型对应的对象,注入到方法参数中。
*/
@Autowired
public void setSf(SessionFactory sessionFactory){
// 调用父类的方法
super.setSessionFactory(sessionFactory);
}
@Override
public List<Person> findAll() {
return getHibernateTemplate().loadAll(Person.class);
}
}
@Qualifier:
作用:在注入数据时,可以配合@Autowired注解一起使用。在按照类型注入的基础上,按照bean的id注入.
注意:
- 在给类的成员变量注入数据时,不能单独使用,需要配合@Autowired注解一起使用
- 在给方法的形参注入数据时候,可以单独使用
@Resource.需要我们手动注入.指定注入容器中的哪一个对象.(推荐使用)
默认情况下(不指定属性),它会先根据变量名称注入,注入不成功;再根据类型注入.
@Component("user")
public class User {
private String name;
@Value("18")
private Integer age;
@Resource(name="car")
private Car car;
- 初始化与销毁方法
@PostConstruct 初始化
@PreDestroy 销毁
@PostConstruct
public void init() {
System.out.println("对象被初始化!");
}
@PreDestroy
public void destory() {
System.out.println("对象被销毁了!");
}
注意:scope为prototype的bean,容器会将创建好的对象实例返回给请求方,之后,容器就不再拥有其引用,请求方需要自己负责当前对象后继生命周期的管理工作,包括该对象的销毁。
所以:scope为singleton的bean的destroy方法则是在容器关闭时执行,而scope为prototype的bean是不会执行destroy方法的。
- 配置文件applicationContext.xml
<?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-4.2.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.2.xsd ">
<context:component-scan base-package="supreme.pojo"></context:component-scan>
</beans>
<context:component-scan base-package="supreme.pojo"></context:component-scan>扫包,扫描包下的所有类,包括子类,子类的子类.
AnnotationConfigApplicationContext:
它是注解使用的容器实现类,作用相当于ClassPathXmlApplicationContext。
@Configuration
作用:把当前类标识为配置类,作用与bean.xml文件相同
@ComponentScans
作用:创建spring容器的时候要扫描的包
@Import
作用:引入其它的配置类
@PropertySource
作用:导入其他属性文件
@Bean:
作用:指定把方法的返回值,放入spring容器中
@Qualifier:
作用:在方法形参上使用,可以独立使用,指定根据bean的id进行注入
方法参数取值注意事项:
-
如果按照参数类型,在spring容器中只有一个对象,则spring可以自动按照类型注入
-
如果按照参数类型,在spring容器中有多个对象,则需要使用@Qualifier注解明确告诉spring,使用哪一个对象