Spring注解方式实现IOC和DI

Spring注解
Spring除了默认的使用xml配置文件的方式实现配置之外,也支持使用注解方式实现配置,这种方式效率更高,配置信息清晰,代码在哪对应的配置就在哪,方便开发阶段修改,推荐使用。

所谓注解就是给程序看的提示信息,很多时候都用来作为轻量级配置的方式。

关于注解的知识点,参看java基础课程中java基础加强部分的内容。

Spring注解方式实现IOC
导入开发包
计算机生成了可选文字:V Referenced Libraries 》 0 》 0 》 0 》 0 》 0 》 0
commons-logging-I .0.4.Jar spring-beans-4.3.25.RELEASE.Jar
spring-context4.3.25.RELEASE.Jar spring-context-support-4.3 需 要 比 之 前
spring-core4.3.25.RELEASE 多 导 入 一 spring-expression4.3.25.R 个 aop 包
spring-test4.3.25.RELEASE 刂 , nn . 3 0 -4.3.25.RELEASE 1 3 r

编写配置文件,并导入context约束

<?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-3.2.xsd

    http://www.springframework.org/schema/context

    http://www.springframework.org/schema/context/spring-context-3.2.xsd

    ">

**可以将以上头信息加入MyEclipse模版,方便后续自动生成。

开启包扫描
在配置文件中,开启包扫描,指定spring自动扫描哪些个包下的类。只有在指定的扫描包下的类上的IOC注解才会生效。

<?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-3.2.xsd

    http://www.springframework.org/schema/context

    http://www.springframework.org/schema/context/spring-context-3.2.xsd

    ">

    <!-- 开启包扫描 -->

    <context:component-scan base-package="cn.tedu.beans"></context:component-scan>

    <!-- 

            <bean id="person" class="cn.tedu.beans.Person"></bean>        

            <bean id="cat" class="cn.tedu.beans.Cat"></bean>        

            <bean id="dog" class="cn.tedu.beans.Dog"></bean>        

     -->

使用注解注册bean
在配置的包中的类上使用@Component注解,则这个类会自动被注册为bean,使用当前类的class为的class,通常情况下使用类名首字母小写为id。

案例:

package cn.tedu.beans;

import org.springframework.stereotype.Component;

@Component

public class Person{

}

bean的id
通常情况下注解注册bean使用类名首字母小写为bean的id,但是如果类名的第二个字母为大写则首字母保留原样.

1 

2 

3 

cn.tedu.beans.Person -->

cn.tedu.beans.PErson -->

cn.tedu.beans.NBA -->

也可以通过在@Component中配置value属性,明确的指定bean的id

案例:

**可以使bean类实现BeanNameAware接口,并实现其中的setBeanName方法,spring容器会在初始化bean时,调用此方法告知当前bean的id。通过这个方式可以获取bean的id信息。

package cn.tedu.beans;

import org.springframework.beans.factory.BeanNameAware;

import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.beans.factory.annotation.Qualifier;

import org.springframework.stereotype.Component;

@Component(“per”)

public class Person implements BeanNameAware{

    @Override

    public void setBeanName(String name) {

            System.out.println("==="+this.getClass().getName()+"==="+name);

    }

}

Spring注解方式实现IOC - 工厂注册bean
Spring默认通过反射创建bean,如果某些bean没有无参构造器或创建过程非常复杂,则无法通过简单的反射创建bean,此时可以通过指定创建bean的工厂,令SpringIOC通过工厂来创建bean,从而进行注册。

可以通过配置文件方式配置bean工厂,同样也可以通过注解配置bean工厂。

配置工厂类
工厂类必须放在包扫描目录下,且被@Component注解修饰

配置工厂类中生产bean的方法
工厂中生产bean的方法要被@Bean修饰

则此方法会被SpringIOC调用,并将返回的对象注册为Spring的bean,默认自动推断id,也可以通过value属性手工指定id。

@Component

public class Pesron5Factory {

@Bean("per5")

public Person5 getInstance(){

    return new Person5("xx");

}

}

Spring注解方式实现DI
导入开发包
计算机生成了可选文字:V Referenced Libraries 》 0 》 0 》 0 》 0 》 0 》 0
commons-logging-I .0.4.Jar spring-beans-4.3.25.RELEASE.Jar
spring-context4.3.25.RELEASE.Jar spring-context-support-4.3 需 要 比 之 前
spring-core4.3.25.RELEASE 多 导 入 一 spring-expression4.3.25.R 个 aop 包
spring-test4.3.25.RELEASE 刂 , nn . 3 0 -4.3.25.RELEASE 1 3 r

编写配置文件,并导入context约束

<?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-3.2.xsd

    http://www.springframework.org/schema/context

    http://www.springframework.org/schema/context/spring-context-3.2.xsd

    ">

配置开启注解实现DI选项

<?xml version="1.0" encoding="UTF-8"?>

<beans xmlns=“http://www.springframework.org/schema/beans”

    xmlns:context="http://www.springframework.org/schema/context"

    xmlns:util="http://www.springframework.org/schema/util"

    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-3.2.xsd

    http://www.springframework.org/schema/context

    http://www.springframework.org/schema/context/spring-context-3.2.xsd

    http://www.springframework.org/schema/util

    http://www.springframework.org/schema/util/spring-util-3.2.xsd

    ">

    <!-- 开启IOC包扫描 -->

    <context:component-scan base-package="cn.tedu.domain"/>

    <!-- 开启注解配置DI -->

    <context:annotation-config></context:annotation-config>

注解方式注入spring内置支持的类型数据 - 非集合类型
spring中可以通过@Value注解来实现spring内置支持的类型的属性的注入。

package cn.tedu.domain;

import org.springframework.beans.factory.annotation.Value;

import org.springframework.stereotype.Component;

@Component

public class Student {

    @Value("zs")

    private String name;

    

    @Value("19")

    private int age;

    

    @Override

    public String toString() {

            return "Student [name=" + name + ", age=" + age + "]";

    }

}

这种方式可以实现spring内置支持类型的注入,但是这种方式将注入的值写死在了代码中,后续如果希望改变注入的值,必须来修改源代码,此时可以将这些值配置到一个properties配置文件中,再在spring中进行引入。

计算机生成了可选文字:person -data.properties id = 888 name:zs

计算机生成了可选文字:〈 ?xml version: ’ ’ . e ” encoding: ” U 丆 F 一 8 ” ? 〉
彐 < b e a n s xmlns = ’ ’ h 亡 亡 : / / . org/schema/beans
xmlns : context: ’ ’ h 亡 亡 : / / 鼽 呲 . springframework . org/schema/context ’
xmlns : xsi: ’ ’ h 亡 亡 : / / . 3 . org/2Æ1/XMLSchema- instance
xsi : schemaLocation: ’ ’ h 亡 亡 : / / 鼽 . springframework . org/schema/beans
h 亡 亡 : / / ‘v’ . springframework . org/schema/beans/spring- beans-3.2 . xs 冒
h 亡 亡 : / / 鼽 ‘v’ . springframework . org/schema/context
h 亡 亡 : / / ‘v’ . springframework . org/schema/context/spring- 00n 亡 ex 亡 . . 2 .
k ! “ 开 启 属 性 注 解 “ 习
〈 c 0 n t e Xt : annotation- config) 〈 /context : annotation- config)
〈 C 0 n t e X t : component-scan base-package: "cn . tedu. beans ”〉 〈 /context : C 0
〈 C 0 n ex : p 0 p e y . p a C e 0
location: ’ ’ 0 乙 ass 0 亡 h :/person - 0 亡 0 . properties 〈 /beans

计算机生成了可选文字:ackage cn.tedu.beans;
impo rt 0 r g . springframework.beans .factory .BeanN. @Com/onent ( “per” )
public 1 a s s P e r s 0 n implement s BeanNameAwaref @value(’ idY’
p rIva e In 1 value( " ) p rIva e r 1 n g name; @Autowired p rivat e Dog dog;
@Autowired p rivat e Cat cat;

注解方式注入spring内置支持的类型数据 - 集合类型
引入util名称空间,通过适当的util标签注册数据

<?xml version="1.0" encoding="UTF-8"?>

<beans xmlns=“http://www.springframework.org/schema/beans”

    xmlns:context="http://www.springframework.org/schema/context"

    xmlns:util="http://www.springframework.org/schema/util"

    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-3.2.xsd

    http://www.springframework.org/schema/context

    http://www.springframework.org/schema/context/spring-context-3.2.xsd

    http://www.springframework.org/schema/util

    http://www.springframework.org/schema/util/spring-util-3.2.xsd

    ">

    <!-- 开启IOC包扫描 -->

    <context:component-scan base-package="cn.tedu.domain"/>

    <!-- 开启注解配置DI -->

    <context:annotation-config></context:annotation-config>

    <!-- 引入Properties文件 -->

    <context:property-placeholder location="classpath:/stu.properties"/>

    

    <!-- 配置集合数据 -->

    <util:list id="l1">

            <value>aaa</value>

            <value>bbb</value>

            <value>ccc</value>

    </util:list>

    <util:set id="s1">

            <value>111</value>

            <value>222</value>

            <value>333</value>

    </util:set>

    <util:map id="m1">

            <entry key="k1" value="v1"></entry>

            <entry key="k2" value="v2"></entry>

            <entry key="k3" value="v3"></entry>

    </util:map>

    <util:properties id="p1">

            <prop key="p1">v1</prop>

            <prop key="p2">v2</prop>

            <prop key="p3">v3</prop>

    </util:properties>

再在类的属性中通过@Value注入赋值

package cn.tedu.domain;

import java.util.List;

import java.util.Map;

import java.util.Properties;

import java.util.Set;

import org.springframework.beans.factory.annotation.Value;

import org.springframework.stereotype.Component;

@Component

public class Student {

    @Value("${name}")

    private String name;

    

    @Value("${age}")

    private int age;

    

    @Value("#{@l1}")

    private List<String> list;

    

    @Value("#{@s1}")

    private Set<String> set;

    

    @Value("#{@m1}")

    private Map<String,String> map;

    

    @Value("#{@p1}")

    private Properties prop;

    

    @Override

    public String toString() {

            return "Student [name=" + name + ", age=" + age + ", list=" + list

                            + ", set=" + set + ", map=" + map + ", prop=" + prop + "]";

    }

}

使用注解注入自定义bean类型数据:
在bean中的属性上通过@Autowired实现自定义bean类型的属性注入

代码:

package cn.tedu.domain;

import java.util.List;

import java.util.Map;

import java.util.Properties;

import java.util.Set;

import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.beans.factory.annotation.Value;

import org.springframework.stereotype.Component;

@Component

public class Student {

    @Autowired

    private Dog dog;

    

    @Autowired

    private Cat cat;

    

    @Override

    public String toString() {

            return "Student [dog="+ dog + ", cat=" + cat + "]";

    }

}

当Spring容器解析到@Component注解时,创建当前类的bean在spring容器中进行管理,在创建bean的过程中发现了@Autowired注解,会根据当前bean类型,寻找在spring中是否存在该类型的bean,找到直接注入,如果找不到还会检查是否有子孙类、实现类存在,如果存在唯一的则自动注入,如果还是没有找到或找到多个无法注入,则还会按照属性名对应id去查找对应的bean,如果存在则注入,如果还是没有找到则抛出异常。

也可以额外配置@Qualifier(value=“dog1”)注解强制要求按照id寻找bean,则此时会直接使用给定的id寻找bean,而不会进行基于类型的匹配。

计算机生成了可选文字:发现@Autowired 开 始 注 入 自 定 义 bean 是否有@QuaIifier 否 按 照 类 型 匹 配
是 否 找 到 唯 一 的 bea n 否 按 照 id 匹 配 是 否 找 到 唯 一 的 bea n 否 抛 出 异 常 结 束 注 入 注 入

**也可以使用@Resource(name=“id”)指定注入给定id的bean,但是这种方式不建议大家使用。

其他注解
@Scope(value=“prototype”)
配置修饰的类的bean是单例还是多例,如果不配置默认为单例

案例:

package cn.tedu.domain;

import org.springframework.context.annotation.Scope;

import org.springframework.stereotype.Component;

@Component

@Scope(“prototype”)

public class Teacher {

}

@Lazy
配置修饰的类的bean采用懒加载机制

案例:

package cn.tedu.domain;

import org.springframework.context.annotation.Lazy;

import org.springframework.stereotype.Component;

@Component

@Lazy

public class Teacher {

    public Teacher() {

            System.out.println("teacher construct..");

    }

}

@PostConstruct
在bean对应的类中 修饰某个方法 将该方法声明为初始化方法,对象创建之后立即执行。

@PreDestroy
在bean对应的类中 修饰某个方法 将该方法声明为销毁的方法,对象销毁之前调用的方法。

案例:

package cn.tedu.beans;

import javax.annotation.PostConstruct;

import javax.annotation.PreDestroy;

import org.springframework.stereotype.Component;

@Component

public class Dog {

    public Dog() {

            System.out.println("Dog...被创建出来了...");

    }

    

    @PostConstruct

    public void init(){

            System.out.println("Dog的初始化方法。。。");

    }

    

    @PreDestroy

    public void destory(){

            System.out.println("Dog的销毁方法。。。");

    }

}

@Controller @Service @Repository @Component
这四个注解的功能是完全相同的,都是用来修饰类,将类声明为Spring管理的bean的。

其中@Component一般认为是通用的注解

而@Controller用在软件分层中的控制层,一般用在web层

而@Service用在软件分层中的业务访问层,一般用在service层

而@Repository用在软件分层中的数据访问层,一般用在dao层

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值