在之前的项目中,我们都是通过xml文件进行bean或者某些属性的赋值,其实还有另外一种注解的方式,在企业开发中使用的很多,在bean上添加注解,可以快速的将bean注册到ioc容器。
1、使用注解的方式注册bean到ioc容器中
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.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">
<!--
使用注解需要如下步骤:
1、添加上述四个注解中的任意一个
2、添加自动扫描注解的组件,此操作需要依赖context命名空间
3、添加自动扫描的标签context:component-scan
注意:当使用注解注册组件和使用配置文件注册组件是一样的,但是要注意:
1、组件的id默认就是组件的类名首字符小写,如果非要改名字的话,直接在注解中添加即可
2、组件默认情况下都是单例的,如果需要配置多例模式的话,可以在注解下添加@scope注解
-->
<!--
定义自动扫描的基础包:
base-package:指定扫描的基础包,spring在启动的时候会将基础包及子包下所有加了注解的类都自动
扫描进ioc容器
-->
<context:component-scan base-package="com.example"></context:component-scan>
</beans>personcontroller.java
package com.example.controller;
import org.springframework.stereotype.controller;
@controller
public class personcontroller {
public personcontroller() {
system.out.println("创建对象");
}
}personservice.java
package com.exxample.service;
import org.springframework.stereotype.service;
@service
public class personservice {
}persondao.java
package com.example.dao;
import org.springframework.stereotype.repository;
@repository("persondao")
@scope(value="prototype")//默认singleton,改为prototype
public class persondao {
}如果想要将自定义的bean对象添加到ioc容器中,需要在类上添加某些注解
spring中包含4个主要的组件添加注解:
- @controller:控制器,推荐给controller层添加此注解
- @service:业务逻辑,推荐给业务逻辑层添加此注解
- @repository:仓库管理,推荐给数据访问层添加此注解
- @component:给不属于以上基层的组件添加此注解
注意:我们虽然人为的给不同的层添加不同的注解,但是在spring看来,可以在任意层添加任意注解,但spring底层是不会给具体的层次验证注解,这样写的目的只是为了提高可读性,最偷懒的方式就是给所有想交由ioc容器管理的bean对象添加component注解
2、定义扫描包时要包含的类和不要包含的类
当定义好基础的扫描包后,在某些情况下可能要有选择性的配置是否要注册bean到ioc容器中,此时可以通过如下的方式进行配置。
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.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">
<context:component-scan base-package="com.example" 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.example.service.personservice"/>
</context:component-scan>
</beans>3、使用@autowired进行自动注入
使用注解的方式实现自动注入需要使用@autowired注解。
personcontroller.java
package com.example.controller;
import com.example.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.example.service;
import com.example.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.example.dao;
import org.springframework.stereotype.repository;
@repository
public class persondao {
public void getperson(){
system.out.println("persondao:getperson");
}
}注意:当使用autowired注解的时候,自动装配的时候是根据类型实现的。
1、如果只找到一个,则直接进行赋值,
2、如果没有找到,则直接抛出异常,
3、如果找到多个,那么会按照变量名作为id继续匹配,
- 匹配上直接进行装配
- 如果匹配不上则直接报异常
personserviceext.java
package com.example.service;
import com.example.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.example.controller;
import com.example.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注解的时候也会有两种情况:
1、找到,则直接装配
2、找不到,就会报错
personcontroller.java
package com.example.controller;
import com.example.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肯定是能够装配上的,如果装配不上就会报错。
4、@autowired可以进行定义在方法上
当我们查看@autowired注解的源码的时候发现,此注解不仅可以使用在成员变量上,也可以使用在方法上。
personcontroller.java
package com.example.controller;
import com.example.dao.persondao;
import com.example.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注解时:
* 1、此方法在bean创建的时候会自动调用
* 2、这个方法的每一个参数都会自动注入值
* @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);
}
}5、自动装配的注解@autowired,@resource
在使用自动装配的时候,出了可以使用@autowired注解之外,还可以使用@resource注解。
1、@autowired:是spring中提供的注解,@resource:是jdk中定义的注解,依靠的是java的标准
2、@autowired默认是按照类型进行装配,默认情况下要求依赖的对象必须存在,@resource默认是按照名字进行匹配的,同时可以指定name属性。
3、@autowired只适合spring框架,而@resource扩展性更好
personcontroller.java
package com.example.controller;
import com.example.dao.persondao;
import com.example.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注解时:
* 1、此方法在bean创建的时候会自动调用
* 2、这个方法的每一个参数都会自动注入值
* @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);
}
}6、泛型依赖注入
为了了解泛型依赖注入,首先我们需要先写一个基本的案例:
student.java
package com.example.bean;
public class student {
}teacher.java
package com.example.bean;
public class teacher {
}basedao.java
package com.example.dao;
import org.springframework.stereotype.repository;
@repository
public abstract class basedao<t> {
public abstract void save();
}studentdao.java
package com.example.dao;
import com.example.bean.student;
import org.springframework.stereotype.repository;
@repository
public class studentdao extends basedao<student>{
public void save() {
system.out.println("保存学生");
}
}teacherdao.java
package com.example.dao;
import com.example.bean.teacher;
import org.springframework.stereotype.repository;
@repository
public class teacherdao extends basedao<teacher> {
public void save() {
system.out.println("保存老师");
}
}studentservice.java
package com.example.service;
import com.example.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.example.service;
import com.example.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.example.service.studentservice;
import com.example.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.example.service;
import com.example.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.example.service;
import com.example.bean.student;
import com.example.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.example.service;
import com.example.bean.teacher;
import com.example.dao.teacherdao;
import org.springframework.beans.factory.annotation.autowired;
import org.springframework.stereotype.service;
@service
public class teacherservice extends baseservice<teacher>{
}总结
以上为个人经验,希望能给大家一个参考,也希望大家多多支持代码网。
发表评论