IOC : 控制反转,把对象创建 , 管理 , 装配的过程交给Spring 来管理
控制 : 谁来控制对象的创建 ? 传统应用程序的对象是由程序本身控制创建的 , 使用Spring后 , 对象是由Spring来创建的
反转 : 程序本身不创建对象 , 而变成被动的接收对象
注解的作用范围:在类的上面,在方法的上面,在属性的上面
注解的格式:
@注解名称(属性名称1=属性值1,属性名称2=属性名称2…)
第一部分:基于注解方式实现对象创建
Spring针对Bean管理中创建对象提供的注解:
- @Component
- @Service
- @Controller
- @repository
上面这四个注解都可以创建Bean实例
等价于配置文件中的< bean id="" class=“全路径”/>
基于注解方式实现对象创建
第一步:引入依赖
手动导入:spring-aop-5.2.6-RELEASE.jar
或者maven自动导入:
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.1.9.RELEASE</version>
</dependency>
第二步:开启组件扫描
1,如果扫描多个包,多个包使用逗号隔开 2,扫描包的上层目录
<!--bean.xml-->
<context:component-scan base-package="com.atmf"></context:component-scan>
第三步:创建类,在类的上面添加对象注解
//在注解里边的value可以省略,如果不写的话,默认值为类名,且首字母小写:就是userService
@Component(value = "userService") //<bean id="" class="全路径"/> 其中value 是跟 id相等的
public class UserService {
public void add(){
System.out.println("service add...........");
}
}
之后,编写测试类进行验证
@Test
public void testService(){
//1,加载配置文件
ApplicationContext context = new ClassPathXmlApplicationContext("bean1.xml");
//2,创建对象
UserService userService = context.getBean("userService", UserService.class);
System.out.println(userService);
userService.add();
}
/*
com.atmf.spring5.service.UserService@55a561cf
service add...........
*/
在组件扫描中,可以更精确一点,进行配置,而不用去扫描所有的包
如果不进行设置use-default-filters属性的值,默认全扫描
use-default-filters=“false” 表示不去使用默认的过滤器,自己去配置filter
关于注解(annotation)的filter有两个
context:include-filter : 设置扫描哪些内容
context:exclude-filter : 设置除了给出的注解,其他名称的注解都扫描(比如:除了@Controller的注解,其他的都扫描)
<!--实例一-->
<context:component-scan base-package="com.atmf" use-default-filters="false">
<context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
</context:component-scan>
<!--实例二-->
<context:component-scan base-package="com.atmf" use-default-filters="false">
<context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
</context:component-scan>
第二部分:基于注解方式实现属性注入
- @AutoWired : 根据属性类型进行自动装配
- @Qualifire :根据属性名称进行注入
- @Resource:可以根据类型注入,可以根据名称注入
- @Vaule:注入普通类型属性
基于@AutoWired进行举例分析
第一步:把UserService和UserDao进行创建,在UserService和UserDao类添加创建对象注解
第二步:在UserService添加UserDao类型属性,在属性上面添加注解
public interface UserDao {
public void add();
}
@Repository
public class UserDaoImpl implements UserDao{
@Override
public void add() {
System.out.println("dao add.....");
}
}
//在注解里边的value可以省略,如果不写的话,默认值为类名,且首字母小写:就是userService
@Component(value = "userService") //<bean id="" class="全路径"/> 其中value 是跟 id相等的
public class UserService {
//在Service里边定义UserDao类型属性,不需要添加set方法,加入属性注解
@Autowired //根据类型进行注入
private UserDao userDao;
public void add(){
System.out.println("service add...........");
userDao.add();
}
}
@Test
public void testService(){
//1,加载配置文件
ApplicationContext context = new ClassPathXmlApplicationContext("bean1.xml");
//2,创建对象
UserService userService = context.getBean("userService", UserService.class);
System.out.println(userService);
userService.add();
}
/*
com.atmf.spring5.service.UserService@55a561cf
service add...........
dao add.....
*/
@AutoWired : 根据属性类型进行自动装配,当一个接口有多个实现类时,就找不到要注入哪一个实现类,这时就可以配合使用@Qualifier:根据名称进行注入(@AutoWire和@Qualifier一起使用)
@Repository(value = "userDaoImpl1")
public class UserDaoImpl implements UserDao{
@Override
public void add() {
System.out.println("dao add.....");
}
}
//在注解里边的value可以省略,如果不写的话,默认值为类名,且首字母小写:就是userService
@Component(value = "userService") //<bean id="" class="全路径"/> 其中value 是跟 id相等的
public class UserService {
//在Service里边定义UserDao类型属性,不需要添加set方法,加入属性注解
@Autowired //根据类型进行注入
@Qualifier(value = "userDaoImpl1")
private UserDao userDao;
public void add(){
System.out.println("service add...........");
userDao.add();
}
}
@Resource:可以根据类型注入,可以根据名称注入(@Resource是java扩展包里边的一个注解:javax.annotation.Resource)
//在注解里边的value可以省略,如果不写的话,默认值为类名,且首字母小写:就是userService
@Component(value = "userService") //<bean id="" class="全路径"/> 其中value 是跟 id相等的
public class UserService {
// @Resource //根据类型进行注入
// private UserDao userDao;
@Resource(name = "userDaoImpl1") //根据名称进行注入
private UserDao userDao;
public void add(){
System.out.println("service add...........");
userDao.add();
}
}
@Value:注入普通类型属性
上边3个注解(@AutoWired,@Qualifier,@Resource)都是对 对象属性 进行注入的
//在注解里边的value可以省略,如果不写的话,默认值为类名,且首字母小写:就是userService
@Component(value = "userService") //<bean id="" class="全路径"/> 其中value 是跟 id相等的
public class UserService {
@Resource(name = "userDaoImpl1") //根据名称进行注入
private UserDao userDao;
@Value(value = "abc")
private String name;
public void add(){
System.out.println("service add..........." + name);
userDao.add();
}
}
@Test
public void testService(){
//1,加载配置文件
ApplicationContext context = new ClassPathXmlApplicationContext("bean1.xml");
//2,创建对象
UserService userService = context.getBean("userService", UserService.class);
System.out.println(userService);
userService.add();
}
/*
com.atmf.spring5.service.UserService@55a561cf
service add...........abc
dao add.....
*/
第三部分:完全注解开发
(1)创建配置类,替代xml文件
@Configuration //@Configuration将SpringConfig类标注为Spring配置类,替代配置文件
@ComponentScan(basePackages = {"com.atmf"})//等价于xml配置文件中的<context:component-scan base-package="com.atmf"></context:component-scan>
public class SpringConfig {}
(2)编写测试类进行验证
@Test
public void testService2(){
//1,加载配置类
ApplicationContext context = new AnnotationConfigApplicationContext(SpringConfig.class);//(参数是配置类的运行时类)
//2,创建对象
UserService userService = context.getBean("userService", UserService.class);
System.out.println(userService);
userService.add();
}
/*
com.atmf.spring5.service.UserService@149e0f5d
service add...........abc
dao add.....
*/