之前讲了Spring 如何创建和使用对象 , 那种初始的方法需要不停的在XML中写入 Bean对象, 如果有多个Bean对象 ,则也是比较麻烦的一种写法 , 有没有更简单的方式呢? Spring 为我们提供了一种更加简单与快捷的方式来存取Bean对象!那就是使用注解的形式 , 注解的本质就是 ,将一些代码给了第三方去完成, 你只需要调用它就行了 , 本质上还是的在XML中存储, 只不过省略你写的过程了. 交给第三方来完成了
告诉系统 扫描那个包下面有我们想要的对象, 配置同样是在XML中 ,XML基础配置不为
有人肯定会说 , 不配行不行 ,让它全部扫描 ,答案当然是可以 , 但是速度会很慢, 就像新华字典 ,按目录指定查找 和一页页查可是区别很大的!
<?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:content="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 https://www.springframework.org/schema/context/spring-context.xsd">
<content:component-scan base-package="com.bit.service"></content:component-scan>
</beans>
想要将对象存储在 Spring 中,有两种注解类型可以实现:
这五个类注解, 使用方法是一致的 , 效果上看也是一致的 ,但是使用场景不一致 , 分别有特定的含义 , 相当于做饭里面不同的柜子 , 有的放碗 , 有的放调料 , 有的放食材 , 虽然作用都是一致的 - 存储数据 , 但是使用场景不同 ,
使用@Controller 存储 bean 的代码
@Controller
public class AATEST {
public String f(){
return "AATEST";
}
}
测试代码
public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext("spring-config.xml");
AATEST aatest = (AATEST) context.getBean("AATEST");
System.out.println(aatest.f());
}
结果图
其他注解的使用方法与@ Controller 一致, 效果也一样, 这里就不一一演示了 .
@Controller:表示的是交互层;
@Servie:服务层;
@Repository:持久层;
@Configuration:配置层。
有人会说了 ,不是5大类注解吗 ,怎么四个 还有个@Component 干嘛去了 ,
答案就是 : @Component :标准一个普通的spring Bean类 ,不代表特殊含义 ,但是@Component可以代替@Repository、@Service、@Controller,因为这三个注解是被@Component标注的 ,算@Component的子类
默认规则 : ID 等于该类的首字母小写的类名 ( 这是因为 , 咱们的类名一般都是大驼峰的命名格式)
特殊规则 : 当第一与第二的字母是大写的时候,ID等于该类的类名
类注解是添加在类上的 ,方法注解是添加在方法上的 , 理论上,如果你把一个类中的所有方法都添加上方法注解 , 那么你的效果跟类注解一模一样 ,
还有一个不方便的地方在于 , 就算你给方法添加注解, 你的类上还必须要有五大类注解之一, 要不然根本获取不到!
说了这么多是不是认为方法注解一无是处, nonono ,如果真的一无是处, 为什么不把它删除了 ,它还是有点用的, 它的作用在于可以通过设置 name 属性给 Bean 对象进⾏重命名操作,然后获取的时候使用name属性就可以了
@Component
public class Users {
@Bean
public User user1() {
User user = new User();
user.setId(1);
user.setName("Java");
return user;
}
}
一般使用了 注解的方式来存放 Bean对象 , 那么有三种方式来获取 它, 当然不是上述的getBean()方法 , 你想,既然存放Bean可以优化, 那为啥获取Bean不能优化呢? 下面依次介绍这三种方法- 这里说一下, 这三种方法就是我们第一节提到的,依赖注入DI的实现
属性注入 属于是: 骂的多, 用的多的方法了! , 为啥如此矛盾, 因为属性注入简单, 骂是因为它简单,出错概率高 , 用也是因为它简单好写!
属性注⼊是使⽤ @Autowired 实现的,将 Service 类注⼊到 Controller 类中。
代码如下
@Service
public class StuSTest {
public User getUser(Integer id , String name){
User user = new User();
user.Id = id;
user.name = name;
return user;
}
}
@Controller
public class StudentTest {
@Autowired
public StuSTest studentTest;
public User getUser(Integer id ,String name){
return studentTest.getUser(id,name);
}
}
通过 给想要的使用 的类 ,上面加上 @Autowired就可以直接使用该类的对象, 快不快! 方便不方便!
这里有个前提 : 属性注入不适用于局部变量!
效果上和你new 该类的对象是一样的
缺点 :
①功能性问题 : 不能注入final(不可变对象)
②通用性问题 : 只适用于Loc容器
③设计原则问题 : 更容易违背单一设计原则
优点 :
使用简单
如题就是在构造方法上面加上@Autowired , 如果只有⼀个构造⽅法,那么 @Autowired 注解可以省略
@Controller
public class UserController2 {
// 注⼊⽅法2:构造⽅法注⼊
private UserService userService;
@Autowired
public UserController2(UserService userService) {
this.userService = userService;
}
public User getUser(Integer id) {
return userService.getUser(id);
}
}
缺点 :
①没有属性注入的方式实现简单
优点:
①可以注入一个不可变的对象
②注入的对象不会被修改
③注入对象会被完全初始化
④通用性更好
如题, Set注入就是在在设置 set ⽅法的时候需要加上 @Autowired 注
解,如下代码所示:
@Controller
public class UserController3 {
// 注⼊⽅法3:Setter注⼊
private UserService userService;
@Autowired
public void setUserService(UserService userService) {
this.userService = userService;
}
public User getUser(Integer id) {
return userService.getUser(id);
}
}
缺点 :
①:不能注入不可变的对象
②:注入的对象是可以被修改的
优点 : 更加符合单一设计原则
① 方法要搭配 5大类注解 去使用
② Bean 注解可以设置 name 属性
③ Bean 默认使用是方法名 , 设置了 name属性 就必须 使用 name的 名字
④使用BeanFactory (Spring创建与使用讲过)不能使用Bean注解
spring依赖注入,是指对象在被创建的时候,由一个调控系统内所有对象的外界实体,将其所依赖的对象的引用,传递给它。 new一个对象的时候,初始化顺序是: 父类静态块,子类静态块,父类属性(先系统默认值,后直接你赋予的值) ,父类构造器,子类属性,子类构造器。
总结: 来做饭来举例: 加入一个菜品有多种做法 , 且所需要的材料不同, 依赖注入, 是动态的 ,是一开始不确定的,是到点做那个去买那个材料 ,而new一个对象是固定的,是需要将材料全部准备好才能在做的时候找到材料.懂了吧?所以说依赖注入,降低了耦合度!
在进⾏类注⼊时,除了可以使⽤ @Autowired 关键字之外,我们还可以使⽤ @Resource 进⾏注⼊,如下代码所示:
@Controller
public class UserController {
// 注⼊
@Resource
private UserService userService;
public User getUser(Integer id) {
return userService.getUser(id);
}
}
相同点 : 都可以进行依赖注入
不同点 :
① :功能支持不同 , @Autowired支持所有方式的注入 ,而@Resource不支持构造方法的注入
②:出身地不同 @Autowired 出生与Spring 框架 , 而@Resource 出生于JDK
③:支持的参数类型不同 : @Resource 支持更多的参数, 而@Autowired只支持require参数