基于注解的DI:使用spring提供的注解,完成java对象的创建,属性赋值。
核心步骤:
(1)在源代码加入注解,例如@Component
(2)在spring的配置文件中,加入组建扫描器标签
<context:component-scan base-package="注解所在的包名"/>
和Component功能相同的创建对象的注解:
@Repository:放在dao接口实现类上面,表示创建dao对象,持久层对象,能访问数据库。
@Service:放在业务层接口实现类上面,表示创建业务层对象,业务层对象有事务的功能。
@Controller:放在控制器类的上面,表示创建控制器对象,属于表示层对象。
控制器对象能接受请求,把请求的处理结果显示给用户。
以上四个注解都能创建对象,但是@Reposity @Service @Controller 有角色说明,表示对象是分层的。
1.@Conmonent
用来创建java对象,相当于bean标签的作用。
默认的对象名称:类名称首字母小写
/** * @author wangqi * @data 2022/8/311748 *@Component,表示创建对象,对象放到容器中,作用是<bean> * 属性:value,表示对象名称,也就是bean的id属性值 * 位置:在类的上面,表示创建此类的对象。 */ //使用value指定对象的名称 @Component(value="mystudent") public class Student { private String name; private int age; public Student(){ System.out.println("Student无参构造方法"); } @Override public String toString() { return "Student{" + "name='" + name + '\'' + ", age=" + age + '}'; } }
<!--声明组件扫描器,使用注解必须加入这个语句 component-scan:翻译过来是组件扫描器,组件是java对象。 属性:base-package 注解在你的项目中的包名。 框架会扫描这个包和子包中的所有类,找类中所有的注解。 遇到注解之后,按照注解表示的功能,去创建对象,给属性赋值。 --> <context:component-scan base-package="com.wangqi.ioc2.项目.ba08"/>
2.扫描多个包的三种方式
2.1使用多次组件扫描器
<context:component-scan base-package="com.wangqi.ioc2.项目.ba08"/>
<context:component-scan base-package="com.wangqi.ioc2.项目.ba09"/>
2.2使用分隔符(;或者,或者 空格),指定多个包
<context:component-scan base-package="com.wangqi.ioc2.项目.ba09;com.wangqi.ioc2.项目.ba08"/>
2.3:指定父包
<context:component-scan base-package="com.wangqi.ioc2.项目"/>
3.属性赋值
3.1简单属性赋值:@Value
属性:value简单类型属性值
位置:(1)在属性定义上面,无需set方法,推荐使用
(2)在set方法上面
@Component("myStudent") public class Student { //进行简单类型的属性赋值:@value //使用外部属性文件中的数据,语法@Value(${"key}) //@Value(value="李四") @Value("${myname}") private String name; //@Value(value="20") @Value("${myage}") private int age; public Student(){ System.out.println("Student无参构造方法"); } @Override public String toString() { return "Student{" + "name='" + name + '\'' + ", age=" + age + '}'; } public void setName(String name) { this.name = name; } public void setAge(int age) { this.age = age; } }
<context:component-scan base-package="com.wangqi.ioc2.项目.ba09"/> <!--读取外部的属性配置文件 property-placeholder:读取properties这样的文件Property --> <context:property-placeholder location="classpath:/ba09/myconf.properties"/> <bean id="mySchool" class="com.wangqi.ioc2.项目.ba10.School"> <property name="name" value="航空大学"/> <property name="address" value="北京的海淀"/> </bean>
myname=agla myage=28
3.2引用类型属性赋值
@Autowired:
spring框架提供的,给引用类型赋值的,使用自动注入原理 ,支持
byName,byType,默认是byType
位置:
(1)在属性定义上面,无需set方法,推荐使用
(2)在set方法上面
@Component("myStudent") public class Student { //进行简单类型的属性赋值:@value //使用外部属性文件中的数据,语法@Value(${"key}) @Value("${myname}") private String name; @Value("${myage}") private int age; //引用类型 //@Autowired:spring框架提供的,给引用类型赋值的,使用自动注入原理 //支持byName,byType,默认是byType //byName自动注入 //1.@Autowired:给引用类型赋值 //2.@Qualifer(value="bean的id"):从容器中找到指定名称的对象,把这个对象赋值给引用类型。 @Autowired @Qualifier(value = "mySchool") private School school; public Student(){ System.out.println("Student无参构造方法"); } @Override public String toString() { return "Student{" + "name='" + name + '\'' + ", age=" + age + ", school=" + school + '}'; } }
<context:component-scan base-package="com.wangqi.ioc2.项目.ba10"/> <!--读取外部的属性配置文件 property-placeholder:读取properties这样的文件Property --> <context:property-placeholder location="classpath:/ba09/myconf.properties"/> <bean id="mySchool" class="com.wangqi.ioc2.项目.ba10.School"> <property name="name" value="航空大学"/> <property name="address" value="北京的海淀"/> </bean>
public class MyTest11 { @Test public void test01(){ String config= "ba11/applicationContext.xml"; ApplicationContext ctx =new ClassPathXmlApplicationContext(config); //myStudent区分大小写 Student student =(Student)ctx.getBean("myStudent"); System.out.println("student=="+student); } }
@Autowired注解的required属性
属性:required:boolean类型的属性,默认true
true:spring在启动的时候,创建容器对象的时候,会检查引用类型是否赋值成功。如果复制失败,终止程序执行,并报错。
false:引用类型赋值失败,程序正常执行,不报错。引用类型的值是null。
@Autowired(required = false) @Qualifier(value = "mySchoolaaaaaaa") private School school; public Student(){ System.out.println("Student无参构造方法"); }
JDK提供的@Resourse自动注入
支持byName,byType,默认是byName
并不是spring提供的,spring只是支持这个注解的使用
(1)在属性定义的上面,无需set方法,推荐使用
(2)在set方法的上面
先使用byName赋值,如果赋值失败再使用byType
说明,使用jdk1.8带有@Resource注解,高于jdk1.8没有这个@Resourse,需要加入一个依赖。
@Resource只使用byName的方式,使用注解属性name="bean的id"
总结:
IoC:管理对象的,把对象放在容器中,创建、赋值,管理依赖关系。
IoC:通过管理对象,实现解耦合。IoC解决处理业务逻辑对象之间的耦合关系,也就是service和dao之间的解耦合。
spring作为容器适合管理什么对象:
(1)service对象,dao对象
(2)工具类对象
不适合交给spring的对象?
(1)实体类
(2)servlet,listener,filter等web中的对象,他们是tomcat创建管理的