在以前的项目中,咱们都是经过xml文件进行bean或者某些属性的赋值,其实还有另一种注解的方式,在企业开发中使用的不少,在bean上添加注解,能够快速的将bean注册到ioc容器。java
applicationContext.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:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.or...
http://www.springframework.or...
http://www.springframework.or...">
<!--
若是想要将自定义的bean对象添加到IOC容器中,须要在类上添加某些注解
Spring中包含4个主要的组件添加注解:
@Controller:控制器,推荐给controller层添加此注解
@Service:业务逻辑,推荐给业务逻辑层添加此注解
@Repository:仓库管理,推荐给数据访问层添加此注解
@Component:给不属于以上基层的组件添加此注解
注意:咱们虽然人为的给不一样的层添加不一样的注解,可是在spring看来,能够在任意层添加任意注解
spring底层是不会给具体的层次验证注解,这样写的目的只是为了提升可读性,最偷懒的方式
就是给全部想交由IOC容器管理的bean对象添加component注解
使用注解须要以下步骤:
一、添加上述四个注解中的任意一个
二、添加自动扫描注解的组件,此操做须要依赖context命名空间
三、添加自动扫描的标签context:component-scan
注意:当使用注解注册组件和使用配置文件注册组件是同样的,可是要注意:
一、组件的id默认就是组件的类名首字符小写,若是非要更名字的话,直接在注解中添加便可
二、组件默认状况下都是单例的,若是须要配置多例模式的话,能够在注解下添加@Scope注解
-->
<!--
定义自动扫描的基础包:
base-package:指定扫描的基础包,spring在启动的时候会将基础包及子包下全部加了注解的类都自动
扫描进IOC容器
-->
<context:component-scan base-package="com.mashibing"></context:component-scan>
</beans>spring
PersonController.java package com.mashibing.controller; import org.springframework.stereotype.Controller; @Controller public class PersonController { public PersonController() { System.out.println("建立对象"); } } PersonService.java package com.mashibing.service; import org.springframework.stereotype.Service; @Service public class PersonService { } PersonDao.java package com.mashibing.dao; import org.springframework.stereotype.Repository; @Repository("personDao") @Scope(value="prototype") public class PersonDao { }
当定义好基础的扫描包后,在某些状况下可能要有选择性的配置是否要注册bean到IOC容器中,此时能够经过以下的方式进行配置。sql
applicationContext.xmlexpress
<?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.or...
http://www.springframework.or...
http://www.springframework.or...">
<context:component-scan base-package="com.mashibing" use-default-filters="false">
<!--
当定义好基础扫描的包以后,能够排除包中的某些类,使用以下的方式:
type:表示指定过滤的规则
annotation:按照注解进行排除,标注了指定注解的组件不要,expression表示要过滤的注解
assignable:指定排除某个具体的类,按照类排除,expression表示不注册的具体类名
aspectj:后面讲aop的时候说明要使用的aspectj表达式,不用
custom:定义一个typeFilter,本身写代码决定哪些类被过滤掉,不用
regex:使用正则表达式过滤,不用
-->
<!-- <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/>-->
<!--指定只扫描哪些组件,默认状况下是所有扫描的,因此此时要配置的话须要在component-scan标签中添加 use-default-filters="false"-->
<context:include-filter type="assignable" expression="com.mashibing.service.PersonService"/>
</context:component-scan>
</beans>app
使用注解的方式实现自动注入须要使用@AutoWired注解。框架
PersonController.java package com.mashibing.controller; import com.mashibing.service.PersonService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; @Controller public class PersonController { @Autowired private PersonService personService; public PersonController() { System.out.println("建立对象"); } public void getPerson(){ personService.getPerson(); } } PersonService.java package com.mashibing.service; import com.mashibing.dao.PersonDao; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; @Service public class PersonService { @Autowired private PersonDao personDao; public void getPerson(){ personDao.getPerson(); } } PersonDao.java package com.mashibing.dao; import org.springframework.stereotype.Repository; @Repository public class PersonDao { public void getPerson(){ System.out.println("PersonDao:getPerson"); } }
注意:当使用AutoWired注解的时候,自动装配的时候是根据类型实现的。学习
一、若是只找到一个,则直接进行赋值,prototype
二、若是没有找到,则直接抛出异常,code
三、若是找到多个,那么会按照变量名做为id继续匹配,
一、匹配上直接进行装配
二、若是匹配不上则直接报异常
PersonServiceExt.java package com.mashibing.service; import com.mashibing.dao.PersonDao; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; @Service public class PersonServiceExt extends PersonService{ @Autowired private PersonDao personDao; public void getPerson(){ System.out.println("PersonServiceExt......"); personDao.getPerson(); } } PersonController.java package com.mashibing.controller; import com.mashibing.service.PersonService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; @Controller public class PersonController { @Autowired private PersonService personServiceExt; public PersonController() { System.out.println("建立对象"); } public void getPerson(){ personServiceExt.getPerson(); } }
还可使用@Qualifier注解来指定id的名称,让spring不要使用变量名,当使用@Qualifier注解的时候也会有两种状况:
一、找到,则直接装配
二、找不到,就会报错
PersonController.java package com.mashibing.controller; import com.mashibing.service.PersonService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.stereotype.Controller; @Controller public class PersonController { @Autowired @Qualifier("personService") private PersonService personServiceExt2; public PersonController() { System.out.println("建立对象"); } public void getPerson(){ personServiceExt2.getPerson(); } }
经过上述的代码咱们可以发现,使用@AutoWired确定是可以装配上的,若是装配不上就会报错。
当咱们查看@AutoWired注解的源码的时候发现,此注解不只可使用在成员变量上,也可使用在方法上。
PersonController.java package com.mashibing.controller; import com.mashibing.dao.PersonDao; import com.mashibing.service.PersonService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.stereotype.Controller; @Controller public class PersonController { @Qualifier("personService") @Autowired private PersonService personServiceExt2; public PersonController() { System.out.println("建立对象"); } public void getPerson(){ System.out.println("personController..."+personServiceExt2); // personServiceExt2.getPerson(); } /** * 当方法上有@AutoWired注解时: * 一、此方法在bean建立的时候会自动调用 * 二、这个方法的每个参数都会自动注入值 * @param personDao */ @Autowired public void test(PersonDao personDao){ System.out.println("此方法被调用:"+personDao); } /** * @Qualifier注解也能够做用在属性上,用来被看成id去匹配容器中的对象,若是没有 * 此注解,那么直接按照类型进行匹配 * @param personService */ @Autowired public void test2(@Qualifier("personServiceExt") PersonService personService){ System.out.println("此方法被调用:"+personService); } }
在使用自动装配的时候,出了可使用@AutoWired注解以外,还可使用@Resource注解,你们须要知道这两个注解的区别。
一、@AutoWired:是spring中提供的注解,@Resource:是jdk中定义的注解,依靠的是java的标准
二、@AutoWired默认是按照类型进行装配,默认状况下要求依赖的对象必须存在,@Resource默认是按照名字进行匹配的,同时能够指定name属性。
三、@AutoWired只适合spring框架,而@Resource扩展性更好
PersonController.java package com.mashibing.controller; import com.mashibing.dao.PersonDao; import com.mashibing.service.PersonService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.stereotype.Controller; import javax.annotation.Resource; @Controller public class PersonController { @Qualifier("personService") @Resource private PersonService personServiceExt2; public PersonController() { System.out.println("建立对象"); } public void getPerson(){ System.out.println("personController..."+personServiceExt2); personServiceExt2.getPerson(); } /** * 当方法上有@AutoWired注解时: * 一、此方法在bean建立的时候会自动调用 * 二、这个方法的每个参数都会自动注入值 * @param personDao */ @Autowired public void test(PersonDao personDao){ System.out.println("此方法被调用:"+personDao); } /** * @Qualifier注解也能够做用在属性上,用来被看成id去匹配容器中的对象,若是没有 * 此注解,那么直接按照类型进行匹配 * @param personService */ @Autowired public void test2(@Qualifier("personServiceExt") PersonService personService){ System.out.println("此方法被调用:"+personService); } }
为了讲解泛型依赖注入,首先咱们须要先写一个基本的案例,按照咱们以前学习的知识:
Student.java package com.mashibing.bean; public class Student { } Teacher.java package com.mashibing.bean; public class Teacher { } BaseDao.java package com.mashibing.dao; import org.springframework.stereotype.Repository; @Repository public abstract class BaseDao<T> { public abstract void save(); } StudentDao.java package com.mashibing.dao; import com.mashibing.bean.Student; import org.springframework.stereotype.Repository; @Repository public class StudentDao extends BaseDao<Student>{ public void save() { System.out.println("保存学生"); } } TeacherDao.java package com.mashibing.dao; import com.mashibing.bean.Teacher; import org.springframework.stereotype.Repository; @Repository public class TeacherDao extends BaseDao<Teacher> { public void save() { System.out.println("保存老师"); } } StudentService.java package com.mashibing.service; import com.mashibing.dao.StudentDao; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; @Service public class StudentService { @Autowired private StudentDao studentDao; public void save(){ studentDao.save(); } } TeacherService.java package com.mashibing.service; import com.mashibing.dao.TeacherDao; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; @Service public class TeacherService { @Autowired private TeacherDao teacherDao; public void save(){ teacherDao.save(); } } MyTest.java import com.mashibing.service.StudentService; import com.mashibing.service.TeacherService; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; import javax.sql.DataSource; import java.sql.SQLException; public class MyTest { public static void main(String[] args) throws SQLException { ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml"); StudentService studentService = context.getBean("studentService",StudentService.class); studentService.save(); TeacherService teacherService = context.getBean("teacherService",TeacherService.class); teacherService.save(); } }
上述代码是咱们以前的能够完成的功能,可是能够思考,Service层的代码是否可以改写:
BaseService.java package com.mashibing.service; import com.mashibing.dao.BaseDao; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; public class BaseService<T> { @Autowired BaseDao<T> baseDao; public void save(){ System.out.println("自动注入的对象:"+baseDao); baseDao.save(); } } StudentService.java package com.mashibing.service; import com.mashibing.bean.Student; import com.mashibing.dao.StudentDao; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; @Service public class StudentService extends BaseService<Student> { } TeacherService.java package com.mashibing.service; import com.mashibing.bean.Teacher; import com.mashibing.dao.TeacherDao; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; @Service public class TeacherService extends BaseService<Teacher>{ }