目录

作用一:创建对象

作用二:为成员变量赋值

注意事项:

1、创建对象时会调用默认的无参构造方法

2、容器内必须有这个值的类

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();
	}
}

Logo

权威|前沿|技术|干货|国内首个API全生命周期开发者社区

更多推荐