1.看图
2.业务层接口IAccountService
package com.itheima.service;
public interface IAccountService {
void saveAccount();
}
3.IAccountServiceImp业务层实现类(里面包含着Resource注入的bean实例,代替持久层的调用)
package com.itheima.service.lmp;
import com.itheima.dao.IAccountDao;
import com.itheima.dao.Imp.IAccountDaoImp;
import com.itheima.service.IAccountService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.ImportResource;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
/*
曾经的xml配置:
<bean id="accountService" class="com.itheima.service.lmp.IAccountServiceImp"
scope=" " init-method=" " destroy-method=" ">
<property name=" " value = " " | ref=" "></property>
</bean>
1.之前讲了四种:
用于创建对象的
他们的作用就和在xml配置文件中编写一个<bean>标签实现的功能是一样
@component:
作用:用于把当前类对象存入spring容器中(spring是一个mapping值【有key和value】)
属性:
value: 用于指定bean的id。当我们不写时,它默认值是当前类名,且首字母小写
@Controller:一般用于表现层
@Service:一般用在持久层
@Repository:一般用在持久层
以上他们三个注解的作用和属性与Component是一模一样的
只是他们三个是spring框架为我们提供明确的三层使用注解: 使我们的三层对象更加清晰
所以说,不属于三层中的任何一层使用的@Component
用于注入数据的(普通/set)
他们的作用就和在xml配置文件中的bean标签中写入一个<property>标签的作用一个
Autowired:
作用:自动按照类型注入。只要容器中有唯一的一个bean对象类型和要注入的变量类型匹配,就可以注入成功
如果ioc容器中没有任何bean的类型和要注入的变量类型匹配,则报错
出现位置:
可以是变量上,也可以是方法上(一般用于方法和类上)
Qualifier:(指定名称注入)
作用:按照类中注入的基础上再按名称注入。它在给类成员注入时不能单独使用。但是在给方法参数注入时可以(稍后讲)
属性:
value:用于指定注入的bean的id。
Resource:(取代Autowired和Qualifier配合)
作用:直接按照bean的id注入。它可以独立使用
属性:
name 用于指定bean的id
额。。。,那为什么不直接用resource,浪费时间?????
总结一下:以上上个注入都只能注入其他的bean类型的数据,而基本类型和String类型无法使用上述的注解实现
另外,集合类型的注入只能通过Xml来实现。
--------------------------------基本数据类型和String类型的注解--------------------------------------
Value
作用:用于注入基本数据类型和String类型的数据
属性:
value:用于指定数据的值。它可以使用spring中的SpEl表达式(也就是spring的el表达式)
SpEL的写法:${表达式}【区分是哪的表达式,那就看表达式出现在哪个位置】
-------------------------------------------
用于改变作用范围的
他们的作用就和在bean标签中使用的scope属性实现的功能是一样的
Scope
作用:用于指定的bean的作用范围
属性:Value("值")
value:指定范围的取值。常用取值:singleton prototype
了解:
和生命周期相关的
他们的作用就和在bean标签中使用init-method和destroy-method的作用是一样的
PreDestroy
指定销毁方法
PostConstruct
初始化方法
------写案例去咯!!!!!!
*/
//@Component(value = "accountService")==》不使用默认id【有两个value也必须得写】
//@Component("accountService")==》默认value也可以
//@Component
@Service("accountService")
//@Service
public class IAccountServiceImp implements IAccountService {
//业务层调用——持久层——调用控制层
//有匹配到的就行,匹配到IAccountDao有,就创建accountDao
//@Autowired
//@Qualifier("accountDao1")
//解锁新技能:在@Autowired类型的基础上,按名称注入@Qualifier("变量名称")
//解决当时如果不能后台修改的毛病,直接选就行,并且他们两个是配合使用的,当出现多个同类型的对象时
//取代上面两个家伙(配合使用的家伙)
@Resource(name = "accountDao")
private IAccountDao accountDao;// 这个对象由于是null,于是出现了空指针异常:解决办法:加入Autowired
//有两个类型一样的,那就按名称 accuntDao1/accountDao2就可以找到
public void saveAccount() {
accountDao.saveAccount();
}
}
4.IAccountDao持久层接口
package com.itheima.dao;
public interface IAccountDao {
void saveAccount();
}
5.实现类1 IAccountDaoImp
package com.itheima.dao.Imp;
import com.itheima.dao.IAccountDao;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
/*
* <bean id="accountDao" class="com.itheima.dao.Imp.IAccountDaoImp"></bean>
* */
@Repository("accountDao1")/*默认值是什么:首字母大写,小写的类名?*/
//@Repository
public class IAccountDaoImp implements IAccountDao {
public void saveAccount() {
System.out.println("保存了账户11111111111");
}
}
5-1.实现类2
package com.itheima.dao.Imp;
import com.itheima.dao.IAccountDao;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
/*
* <bean id="accountDao" class="com.itheima.dao.Imp.IAccountDaoImp"></bean>
* */
//@Repository("accountDao")/*默认值是什么:首字母大写,小写的类名?*/
@Repository("accountDao2")
public class IAccountDaoImp2 implements IAccountDao {
public void saveAccount() {
System.out.println("保存了账户2222222222222");
}
}
6.依赖写入pom.xm
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.0.2.RELEASE</version>
</dependency>
<!-- 添加resource注解依赖 -->
<dependency>
<groupId>javax.annotation</groupId>
<artifactId>jsr250-api</artifactId>
<version>1.0</version>
</dependency>
7.配置文件bean.xml(管理bean的调度分配)
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-4.0.xsd" >
<!-- 告知spring在创建容器时要扫描包(他就会扫描这个包里面的注解,通过对应机制),
配置所需要的标签不是在beans约束,而是一个名称为context名称空间和约束中(导入:声明也要加、约束也要加)
解释:
1. 当你把注解写在实现类中的时候,例如@component,它是通过类创建对象的,然后放入到spring容器中
但是呢!他不知道哪个类需要用的哪个注解,所以他需要扫描包,把它们都找出来,通知一波,哎我找到你,
此时注解的功能得到调用(这里使用的广播机制),而原来的spring容器的配置机制变成了广播扫描机制。
-->
<context:component-scan base-package="com.itheima"></context:component-scan>
</beans>
8.表现类Client
package com.itheima.ui;
import com.itheima.dao.IAccountDao;
import com.itheima.dao.Imp.IAccountDaoImp;
import com.itheima.service.IAccountService;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
//模拟一个表现层,用于调用业务层
public class Client {
public static void main(String[] args) {
//核心容器获取对象ac
ApplicationContext ac = new ClassPathXmlApplicationContext("bean.xml");
//第一种:普通的xml配置id,通过实现类来创建id中的名称来作为对象【<bean id="accountService" class="com.itheima.service.lmp.IAccountServiceImp"/>】
// IAccountService as = (IAccountService) ac.getBean("accountService[指定id]");
//第二种:这里使用的是@Component注解:id的名称默认是类名【那@Component(value也可以指定id名的,不使用类名自己定义也可【value就可以】)】
IAccountService as = (IAccountService) ac.getBean("accountService");
// System.out.println(as);
// IAccountDao ado = ac.getBean("IAccountDaoImp", IAccountDao.class);
// System.out.println(ado);
as.saveAccount();
}
}
/*
*dao: Client调用IAccountServiceImp调用IAccountDaoImp(创建实例化对象的时候)
* service:业务返回:IAccountDao ——>IAccountService——>显示Client
*/
/*IAccountService as = new IAccountServiceImp();普通用法:独立就用spring容器*/
9.注解机制
(1)类级别的注解:如@Component、@Repository、@Controller、@Service注解,都是添加在类上面的类级别注解。
Spring容器根据注解的过滤规则扫描读取注解Bean定义类,并将其注册到Spring IoC容器中。
(2)类内部的注解:如@Autowire、@Value、@Resource以及EJB和WebService相关的注解等,都是添加在类内部的字段或者方法上的类内部注解。
SpringIoC容器通过Bean后置注解处理器解析Bean内部的注解。