一、传统XML方式
<!-- 将User对象交给spring容器管理 -->
<bean name="user" class="com.mark.test.User"></bean>
二、IoC注解方式(配置组件扫描)
1.开启使用注解开发,配置组件扫描
指定扫描base-package="包",需要使用注解(扫描时会扫描指定包下的所有子孙包)
<!-- 自动扫描dao和service包(自动注入)
-->
<context:component-scan base-package="com.mark">
<context:include-filter type="regex" expression=".*.dao.impl.*,.*.service.impl.*"/>
<context:include-filter type="regex" expression=".*.*.dao.impl.*,.*.*.service.impl.*"/>
</context:component-scan>
2.在类上使用注解@Component|Controller|Service|Repository/@Scope
相当于<bean name="userDao" class="com.mark.test.UserDaoImpl"></bean>
//相当于<bean name="userDao" class="com.mark.test.UserDaoImpl"></bean>
@Component("userDao")
public class UserDaoImpl implements UserDao{
private String name;
//...
}
如果不指定("name名称") ,默认的bean名字为这个类的类名首字母小写
(1) @Component("name名称") --原始所有通用类注解
起初所有类注解都是@Component,后来为了开发方便,层次分明,衍生出@Service、@Controller、@Repository注解
(2) @Controller("name名称") --Web层
(3) @Service("name名称") --Service层
(4) @Repository("name名称") --Dao层
(5) @Scope(scopeName="singleton|prototype")--对象作用范围注解,默认单例
默认为单例模式,Struts2需要将设置为prototype原型模式,每次创建一个Action,就new一个新的实例
三、DI注解方式设置属性值@Value|@Autowired
1.普通属性@Value("value值")(可以没有set方法)
(1)如果属性有set方法,需要将属性注入的注解加入到set方法上
//相当于<bean name="userDao" class="com.mark.test.UserDaoImpl"></bean>
@Component("userDao")
public class UserDaoImpl implements UserDao{
private String name;
@Value("mark")
public void setName(String name){
this.name = name;
}
//...
}
(2)如果属性没有set方法,需要将属性注入的注解加入到属性上(反射,破坏封装性)
将注解放到成员变量上方,通过反射的Field进行赋值,破坏了对象的封装性
//相当于<bean name="userDao" class="com.mark.test.UserDaoImpl"></bean>
@Component("userDao")
public class UserDaoImpl implements UserDao{
@Value("mark")
private String name;
/*@Value("mark")
public void setName(String name){
this.name = name;
}*/
//...
}
2.对象类型属性@Autowired{@Qualifier 可选}|@Resource
在启动spring IoC时,容器自动装载了一个AutowiredAnnotationBeanPostProcessor后置处理器,当容器扫描到@Autowied、@Resource或@Inject时,就会在IoC容器自动查找需要的bean,并装配给该对象的属性
在使用@Autowired时,首先在容器中查询对应类型的bean
如果查询结果刚好为一个,就将该bean装配给@Autowired指定的数据
如果查询的结果不止一个,那么@Autowired会根据名称来查找。
如果查询的结果为空,那么会抛出异常。解决方法时,使用required=false
(1)自动装配@Autowired{@Qualifier("name名称")}
(1)@Autowired(不存在多个类型一致的对象)---按照类型注入,扫描相同类型
public Interface UserService{
public void getUserList();
}
@Service("userService")
public class UserServiceImpl implements UserService{
@Autowired
private UserDao userDao; //父类引用指向子类对象
public void getUserList(){
List<User> userLists = userDao.getUserList();
}
}
(2)@Qualifier("name名称")(存在多个类型一致的对象)--按照名称注入,直接去查找指定名称bean
public Interface UserService{
public void getUserList();
}
@Service("userService01")
public class UserServiceImpl01 implements UserService{
@Autowired
private UserDao userDao;
public void getUserList(){
List<User> userLists = userDao.getUserList();
}
}
@Service("userService02")
public class UserServiceImpl02 implements UserService{
@Autowired
private UserDao userDao;
public void getUserList(){
List<User> userLists = userDao.getUserList();
}
}
@Controller
@RequestMapping("/user")
public class UsernfoControl {
@Autowired
@Qualifier("userService01")
UserService userService;
@RequestMapping("/getUser")
@ResponseBody
public List<User> showUserInfo(){
//....
}
}
(2)手动装配@Resource("name名称") --按照名称注入,直接去查找指定名称bean
可以替代@Autowired+@Qualifier("name名称")方法实现按照名称注入
四、初始化和销毁方法注解@PostConstruct | @PreDestroy
1.初始化方法注解(相当于bean标签中的init-method属性)
@PostConstruct
public void initMethod(){
System.out.println("初始化方法!");
}
2.销毁方法注解(相当于bean标签中的destroy-method属性)
@PreDestroy
public void destroyMethod(){
System.out.println("销毁方法!");
}