1. 前2天小结
【理解】通过Spring获取对象的3种条件:无参构造方法、静态工厂方法、实例方法;
【理解】由Spring管理的对象的作用域及生命周期:单例、懒加载、生命周期方法;
【重要】通过SET方式注入属性的值,理解value和ref的使用;
【了解】通过构造方法注入属性的值;
【了解】注入集合类型的属性的值,包括:List / Set / Map;
【重要】注入Properties类型的属性的值,读取*.properties文件;
【理解】自动装配的作用,取值为byName与byType的特性;
【重要】Spring表达式
2. Spring注解(Annotation)
2.1. 基本概念
例如@Override就是注解,在Spring中定义了一些注解,可以取代在Spring的XML文件中的配置!
2.2. 通过Spring获取对象
案例目标:创建cn.tedu.spring.dao.UserDao类,然后,创建cn.tedu.spring.test.SpringTest类,通过Spring获取UserDao的对象。
在Spring中,有几种通用注解:
@Component
@Controller
@Service
@Repository
这些注解是添加在类的声明之前的,表示这个类是一个“组件”,是希望由Spring进行管理的!
以上4个注解中,@Component表示“通用组件类”,@Controller表示“控制器类”,@Service表示“业务类”,@Repository表示“数据访问类/持久层处理的类”,这4个注解只有语义的区别,从功能和用法上来说,是完全一样的!即,如果愿意的话,可以用@Service注解添加在控制器类的声明之前,但是,不推荐这样做。
仅仅只是添加注解是不够的,还需要在Spring的配置文件中开启组件扫描:
<context:component-scan base-package="cn.tedu.spring.dao" />以上配置中,base-package表示根包,即当配置为cn.tedu.spring时,其子级包例如cn.tedu.spring.dao或cn.tedu.spring.service等都在扫描范围之内!
如果没有显式的指定bean-id,默认为使用类名且首字母改为小写,例如UserDao类的bean-id就是userDao。
以上注解都可以添加配置,例如@Service("bean-id")。
小结:通用注解共4个,其功能、用法都是完全相同的,只是表达的语义不同,添加的注解的类,并且在组件扫描范围之内,就会被Spring所管理,在配置组件扫描时,配置的包是“根包”,其范围不宜过大,在添加注解时,还可以自定义bean-id。
2.3. 作用域与生命周期
由Spring管理的对象,默认是饿汉式的单例的,通过在类的声明之前添加注解@Lazy可以调整:
@Component("userDao")
@Lazy(true)
public class UserDao {
}还可以通过@Scope("singleton")或@Scope("prototype")注解调整是否为单例的:
@Service
@Scope("prototype")
public class UserService {
}关于生命周期方法,依然是先自定义生命周期方法,在初始化方法之前添加@PostConstruct注解,在销毁方法之前添加@PreDestroy注解,这2个注解都是Java EE的注解,来自javax包下,所以,在使用之前,需要为当前项目添加Tomcat运行环境,代码部分例如:
@Component("userDao")
public class UserDao {
public UserDao() {
System.out.println("UserDao的构造方法被执行!");
}
@PostConstruct
public void init() {
System.out.println("UserDao.init()");
}
@PreDestroy
public void destroy() {
System.out.println("UserDao.destroy()");
}
}注意:如果导入他人的项目,或者本机更换了Tomcat软件,都需要重新勾选项目属性中的Targeted Runtimes中的Tomcat。
2.4. 【重要】自动装配
假设在UserDao中存在public void findUserByUsername()方法,然后,在UserService中声明了private UserDao userDao;属性,并且,存在public void login()方法,在方法内部,调用了userDao的findUserByUsername()方法:
@Component("userDao")
public class UserDao {
public void findUserByUsername() {
System.out.println("UserDao.findUserByUsername()");
}
}
@Service
public class UserService {
private UserDao userDao;
public void login() {
System.out.println("UserService.login()");
userDao.findUserByUsername();
}
}在需要自动装配属性值的属性之前,添加@Autowired注解,就可以实现自动装配:
@Autowired
private UserDao userDao;注意:使用注解的自动装配不需要为属性添加SET方法!
添加@Autowired实现自动装配,其装配方式是byType的,所以,在使用时,需要确保“其对应的值在Spring容器中应该是有且仅有1个的”!
通过@Resource注解也可以实现自动装配!它是优先根据byName实现自动装配,在没有显式的指定bean-id的情况下,如果无法byName装配,则会尝试根据byType实现自动装配。
在实际使用时,可以自由选取以上2个注解中的任何一个!因为,在实际应用中,命名应该是规范的,并且,匹配类型的也应该是有且仅有1个。
以上2个注解中,@Autowired是Spring的环境中的注解类,而@Resource是Java EE环境中的注解类。