目录
作用一:创建对象
作用二:为成员变量赋值
3、除@Autowired注解外,@Inject,@Resource注解也可赋值
4、当类符合扫描的要求时,通过该类实现的接口也可获取该类的对象
.xml文件中context:component-scan标签有如下两个作用:
1、扫描包内及其子包内的所有“类”(不包含接口),并为添加了@Service、@Component、@Controller、@Repository修饰的类创建对象并存入IOC容器
2、@Service、@Component、@Controller、@Repository修饰的类中含有@Autowired修饰的成员变量,则创建对象时会从IOC容器中取值为该成员变量赋值
接下来分别举例演示这两个作用:
作用一:
扫描包内及其子包内的所有“类”(不包含接口),并为添加了@Service、@Component、@Controller、@Repository修饰的类创建对象并存入IOC容器
首先创建一个UserInfoDao类,实现IUserInfoDao接口:
package club.affengkuang.userinfo.dao;
@Service
public class UserInfoDao implements IUserInfoDao {
}
项目中的目录结构如下:
然后创建一个application.xml文件,在其中加入context:component-scan标签,其中base-package标签属性的作用是设置要扫描的包名,扫描的范围包括包内及子包内的类:
<?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"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:util="http://www.springframework.org/schema/util"
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.3.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-4.3.xsd">
<context:component-scan base-package="club.affengkuang"></context:component-scan>
</beans>
然后在测试类中执行第10行代码时,创建IOC容器的时候,便会执行到application.xml文件中,通过context:component-scan标签,对club.affengkuang包中的类进行扫描,当发现UserInfoDao类带有@Service注解时,便创建一个该类对象,然后回到测试类中,就可以获取并在控制台打印该对象:
package club.affengkuang.test;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import club.affengkuang.userinfo.dao.UserInfoDao;
public class Test {
public static void main(String[] args) {
ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("application.xml");
UserInfoDao userInfoDao = applicationContext.getBean(UserInfoDao.class);
System.out.println(userInfoDao);
applicationContext.close();
}
}
作用二:
@Service、@Component、@Controller、@Repository修饰的类中含有@Autowired修饰的成员变量,则创建对象时会从IOC容器中取值为该成员变量赋值
首先在UserInfoDao类中加入@Autowired的属性及获取属性值的get方法:
package club.affengkuang.userinfo.dao;
import java.util.Date;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service
public class UserInfoDao implements IUserInfoDao {
@Autowired
private Date date;
public Date getDate() {
return date;
}
}
由于Date是引用类型,所以此时在IOC容器中并没有该类的对象可用来给date属性赋值,所以需要在application.xml文件中加入第7行代码,这样创建IOC容器时,里面就会有Date类对象,可以给date属性赋值了:
<?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.3.xsd">
<bean class="java.util.Date"></bean>
<context:component-scan base-package="club.affengkuang"></context:component-scan>
</beans>
然后在测试类中获取UserInfoDao对象,然后调用getDate方法,发现date属性确实在容器中被赋了值:
package club.affengkuang.test;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import club.affengkuang.userinfo.dao.UserInfoDao;
public class Test {
public static void main(String[] args) {
ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("application.xml");
UserInfoDao userInfoDao = applicationContext.getBean(UserInfoDao.class);
System.out.println(userInfoDao.getDate());
applicationContext.close();
}
}
注意事项:
1、创建对象时会调用默认的无参构造方法
也就是说如果在UserInfo类中添加一个构造方法,让默认的构造方法失效,则会报出异常:
package club.affengkuang.userinfo.dao;
import java.util.Date;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service
public class UserInfoDao implements IUserInfoDao {
public UserInfoDao(int age) {
System.out.println(age);
}
@Autowired
private Date date;
public Date getDate() {
return date;
}
}
2、容器内必须有这个值的类
当在IOC容器中,为@Autowired修饰的属性赋值时,如果该属性为引用类型,则容器中要有该引用类型对象;但当容器中没有时,还可以在@Autowired后加(required:false),这时就不会因此而报错,而是将该属性的值赋为null:
package club.affengkuang.userinfo.dao;
import java.util.Date;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service
public class UserInfoDao implements IUserInfoDao {
@Autowired(required=false)
private Date date;
public Date getDate() {
return date;
}
}
3、除@Autowired注解外,@Inject,@Resource注解也可赋值
但这两个注解在实际应用中并不常见,而且@Inject注解没有reqired属性
4、当类符合扫描的要求时,通过该类实现的接口也可获取该类的对象
例如,IUserInfoDao是UserInfoDao实现的接口:
package club.affengkuang.userinfo.dao;
import java.util.Date;
public interface IUserInfoDao {
Date getDate();
}
则在测试类中可以使用接口名获取UserInfoDao类对象,但接口中要有getDate()抽象方法:
package club.affengkuang.test;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import club.affengkuang.userinfo.dao.IUserInfoDao;
public class Test {
public static void main(String[] args) {
ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("application.xml");
IUserInfoDao userInfoDao = applicationContext.getBean(IUserInfoDao.class);
System.out.println(userInfoDao.getDate());
applicationContext.close();
}
}