`

第五章 注释注入

阅读更多
 注释方法注入
采用注释方式的前提条件,
1.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-2.5.xsd
           http://www.springframework.org/schema/context
           http://www.springframework.org/schema/context/spring-context-2.5.xsd">              
     <context:annotation-config/>    
</beans>

蓝色部分为添加的内容,这一部分内容隐式注册注释处理器
AutowiredAnnotationBeanPostProcessor,CommonAnnotationBeanPostProcessor,PersistenceAnnotationBeanPostProcessor

2.依赖包的导入
见下图:



只需要选中 Spring2.5 J2EE 此选项后, 其他的项会自动选中,包括后面要学习的AOP的包也导入了.

在java代码中,可以使用@Autowired或 @Resource注释方式进行装配,这两个注解的区别是:
@Autowired默认按类型装配
@Resource 默认按名称装配,当找不到与名称匹配的bean时,再按类型装配.

@Autowired或 @Resource两者的区别:
@Autowired: Spring提供,使用后程序会具有侵入性.
@Resource: JDK提供,移植性强,推荐使用, 可以看到支撑类是: import javax.annotation.Resource; 只要是JDK1.5以上版本,JDK内置了此注释支撑类.

用法:
用在属性上
public class FruitServiceImpl implements FruitService {
@Resource
private FruitDao fruitDao;

@Override
public void create() {
fruitDao.create();
}

public void setFruitDao(FruitDao fruitDao) {
this.fruitDao = fruitDao;
}
}
配置文件:
<?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-2.5.xsd
           http://www.springframework.org/schema/context
           http://www.springframework.org/schema/context/spring-context-2.5.xsd">
<context:annotation-config />
<bean id="fruitDao" class="dao.impl.FruitDaoImpl" />
<bean id="fruitService" class="service.impl.FruitServiceImpl" />
</beans>
可以看到这里只是在容器中配置了两个bean对象, 他们之间并没有任何关系.但是在Java文件中,我们采用了注释语法,
这个时候@Resource注释语法会根据属性名称在Spring容器中去寻找和属性名称同名id的bean对象,然后将其注入到属性中.
Test:
public class Test {
public static void main(String[] args) {
ApplicationContext acx = new ClassPathXmlApplicationContext(
"chapter2.xml");
FruitService fruitService = (FruitService) acx.getBean("fruitService");
fruitService.create();
}
}

更改配置文件:
<bean id="myFruitDao" class="dao.impl.FruitDaoImpl" />
这个时候可以看到myFruitDao和属性名称并没有对应,但是执行Test文件后,可以看到还是成功执行了方法,为什么呢?
验证了我们刚才所说的,如果名称没有对应上,就会按类型自动对应,所以会执行成功.

我们还可以给@Resource加上name,请看下面的语法
public class FruitServiceImpl implements FruitService {
@Resource(name="myFruitDao")
private FruitDao fruitDao;

@Override
public void create() {
fruitDao.create();
}

public void setFruitDao(FruitDao fruitDao) {
this.fruitDao = fruitDao;
}
}
再次执行Test,同样可以执行成功.

用上属性的set方法上
public class FruitServiceImpl implements FruitService {

private FruitDao fruitDao;

@Override
public void create() {
fruitDao.create();
}

@Resource(name="myFruitDao")
public void setFruitDao(FruitDao fruitDao) {
this.fruitDao = fruitDao;
}
}
可以看到,用在属性上,或者用上属性的set方法上,效果是一模一样的,没有任何区别

注意:如果我这样配置:
@Resource(name="myFruitDaosss")
public void setFruitDao(FruitDao fruitDao) {
this.fruitDao = fruitDao;
}
而配置文件中又没有提供id为myFruitDaosss的bean,这个时候是会报错的:
Exception in thread "main" org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'fruitService': Injection of resource methods failed; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 'myFruitDaosss' is defined

@Autowired
请看下面的代码:
public class FruitServiceImpl implements FruitService {

private FruitDao fruitDao;

@Override
public void create() {
fruitDao.create();
}

@Autowired
public void setFruitDao(FruitDao fruitDao) {
this.fruitDao = fruitDao;
}
}
运行Test文件,可以看到效果一样.

同样,我们也可以把@Autowired改成按名称装配
public class FruitServiceImpl implements FruitService {
@Autowired()
@Qualifier("myaFruitDao")
private FruitDao fruitDao;

public void create() {
fruitDao.create();
}

public void setFruitDao(FruitDao fruitDao) {
this.fruitDao = fruitDao;
}
}
但是这里需要注意的是:
@Autowired()
@Qualifier("myaFruitDao")
private FruitDao fruitDao;
这两句只能用在属性上,不能用上方法上.

@Autowired的required属性
@Autowired(required=true)
@Qualifier("myFruitDao")
required=true : 必须为属性注入值,
required=false: 不是必须注入值,如果找不到对应的值注入,会注入null

示例:
@Autowired(required=false) @Qualifier("myXXXXXXFruitDao")
当配置文件中没有对应ID的Bean时,会出现java.lang.NullPointerException空指针异常

 通过在classpath自动扫描方式把组件纳入到spring容器中管理.
Spring2.5引入了组件自动扫描机制,他可以在类路径下寻找标注了@Component, @Service, @Controller, @Repository注解的类, 并把这些类纳入进Spring容器中管理,它的作用,和在XML文件中使用Bean节点配置组件是一样的,要使用自动扫描机制,我们需要打开以下配置信息
<?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-2.5.xsd
           http://www.springframework.org/schema/context
           http://www.springframework.org/schema/context/spring-context-2.5.xsd">
<context:component-scan base-package="com.wdpc.springdemo" />
</beans>
<context:component-scan base-package="com.wdpc.springdemo" />这一项配置了需要扫描的包,包含子包.

@Service: 用于标注业务层的类
@Controller: 用于标注控制层,如Action
@Repository: 用于标注Dao层
@Component: 用于标注组件层, 当组件不好归类的时候,可以用此标注
这四个注释功能一样,只不过是在逻辑层次上达到一个区分的目的.其实,用哪一个都可以.只要类上用到了这些注释,就是告诉Spring,我这个类要交给Spring管理.效果相当于在配置文件中配置的<bean id=”**” class=”**”/>

通过扫描机制, 基本上可以达到配置文件基本为空的效果, 这是Spring2.5新推出的功能, 老系统不能运用, 但是新系统中, 此功能运用的非常多.

示例:
Dao层:
package com.wdpc.springdemo.dao.impl;

import org.springframework.stereotype.Repository;

import com.wdpc.springdemo.dao.FruitDao;

@Repository
public class FruitDaoImpl implements FruitDao {
public void create() {
System.out.println("Dao层方法create被调用");
}
}
服务层:
package com.wdpc.springdemo.service.impl;

import org.springframework.stereotype.Service;

import com.wdpc.springdemo.dao.FruitDao;
import com.wdpc.springdemo.service.FruitService;

@Service
public class FruitServiceImpl implements FruitService {

private FruitDao fruitDao;

public void create() {
fruitDao.create();
}

public void setFruitDao(FruitDao fruitDao) {
this.fruitDao = fruitDao;
}
}
这个时候,我将Dao层,服务层的两个实现类交给Spring管理了,相当于以前配置了两个Bean,这个时候我们可以验证一下,我们是否可以从容器中获取对象
Test:
package com.wdpc.springdemo.service;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import com.wdpc.springdemo.dao.FruitDao;

public class Test {

public static void main(String[] args) {
ApplicationContext acx = new ClassPathXmlApplicationContext(
"chapter2.xml");
FruitDao fruitDao = (FruitDao)acx.getBean("fruitDaoImpl");
FruitService fruitService = (FruitService) acx.getBean("fruitServiceImpl");
System.out.println(fruitDao);
System.out.println(fruitService);
}
}
这里需要注意的是,当对象交给Spring管理后,Spring给对象起的ID名称是类的简单名称, 即类全名,但是首字母小写

自定义名称:
Dao层:
package com.wdpc.springdemo.dao.impl;

import org.springframework.stereotype.Repository;

import com.wdpc.springdemo.dao.FruitDao;

@Repository("fruitDao")
public class FruitDaoImpl implements FruitDao {
public void create() {
System.out.println("Dao层方法create被调用");
}
}

服务层:
package com.wdpc.springdemo.service.impl;

import org.springframework.stereotype.Service;

import com.wdpc.springdemo.dao.FruitDao;
import com.wdpc.springdemo.service.FruitService;

@Service("fruitService")
public class FruitServiceImpl implements FruitService {

private FruitDao fruitDao;

public void create() {
fruitDao.create();
}

public void setFruitDao(FruitDao fruitDao) {
this.fruitDao = fruitDao;
}
}
Test:
public class Test {
public static void main(String[] args) {
ApplicationContext acx = new ClassPathXmlApplicationContext(
"chapter2.xml");
FruitDao fruitDao = (FruitDao)acx.getBean("fruitDao");
FruitService fruitService = (FruitService) acx.getBean("fruitService");
System.out.println(fruitDao);
System.out.println(fruitService);
}
}

 改变对象的范围(单例或非单例)
@Repository("fruitDao")
@Scope("prototype")
加上@Scope("prototype")此注释即可,这个时候每次获取对象都会是一个新对象

 对象初始化方法和销毁方法的配置
@Repository("fruitDao")
@Scope("prototype")
public class FruitDaoImpl implements FruitDao {
public void create() {
System.out.println("Dao层方法create被调用");
}

@PostConstruct
public void init(){
System.out.println("调用init");
}

@PreDestroy
public void destory(){
System.out.println("调用destory");
}
}
如果对象是非单例模式,这个时候可以看到init方法会调用两次,而destroy方法不会调用.

将Dao层注入到服务层:
@Service("fruitService")
public class FruitServiceImpl implements FruitService {
@Resource(name="fruitDao")
private FruitDao fruitDao;

public void create() {
fruitDao.create();
}

public void setFruitDao(FruitDao fruitDao) {
this.fruitDao = fruitDao;
}
}

  • 大小: 10.2 KB
分享到:
评论

相关推荐

    第五章 注释的注入

    NULL 博文链接:https://x125521853.iteye.com/blog/658079

    SQL注入攻击与防御

    第5章 SQL盲注利用 171 5.1 概述 172 5.2 寻找并确认SQL盲注 173 5.2.1 强制产生通用错误 173 5.2.2 注入带副作用的查询 173 5.2.3 拆分与平衡 173 5.2.4 常见的SQL盲注场景 175 5.2.5 SQL盲注技术 176 5.3 使用基于...

    SQL注入攻击与防御(安全技术经典译丛)

    第5章 SQL盲注利用  5.1 概述  5.2 寻找并确认SQL盲注  5.2.1 强制产生通用错误  5.2.2 注入带副作用的查询  5.2.3 拆分与平衡  5.2.4 常见的SQL盲注场景  5.2.5 SQL盲注技术  5.3 使用基于时间的...

    利用输入法注入DLL

    包中的第5个文件夹。 最后的最后,再介绍一个未公开函数InitializeLpkHooks,这个函数在网上能找到的资料更 少,只有一个声明而已。但是它名称中最后那个“Hooks”误导了我,我以为又是一个可以 用来注入DLL的...

    Spring in Action(第2版)中文版

    第5章使用数据库 5.1spring的数据访问哲学 5.1.1了解spring数据访问的异常体系 5.1.2数据访问的模板化 5.1.3使用dao支持类 5.2配置数据源 5.2.1使用jndi数据源 5.2.2使用数据源连接池 5.2.3基于jdbc驱动的...

    Spring in Action(第二版 中文高清版).part2

    第5章 使用数据库 5.1 Spring的数据访问哲学 5.1.1 了解Spring数据访问的异常体系 5.1.2 数据访问的模板化 5.1.3 使用DAO支持类 5.2 配置数据源 5.2.1 使用JNDI数据源 5.2.2 使用数据源连接池 5.2.3 基于...

    Spring in Action(第二版 中文高清版).part1

    第5章 使用数据库 5.1 Spring的数据访问哲学 5.1.1 了解Spring数据访问的异常体系 5.1.2 数据访问的模板化 5.1.3 使用DAO支持类 5.2 配置数据源 5.2.1 使用JNDI数据源 5.2.2 使用数据源连接池 5.2.3 基于...

    WEB安全测试

    第5章 篡改输入 85 5.1 截获和修改POST请求 86 5.2 绕过输入限制 89 5.3 篡改URL 90 5.4 自动篡改URL 93 5.5 测试对URL长度的处理 94 5.6 编辑Cookie 96 5.7 伪造浏览器头信息 99 5.8 上传带有恶意文件名的文件 101 ...

    Java Web编程宝典-十年典藏版.pdf.part2(共2个)

    第5章 Web应用的缔造者 ——Servlet技术 5.1 本章学习任务 5.1.1 本章知识体系 5.1.2 实例开发任务 5.2 与时俱进——了解Servlet技术 5.2.1 初步认识Servlet 5.2.2 Servlet与JSP的区别 5.3 为我所用——Servlet技术...

    Pro .NET Best Practices .net最佳实践 英文版

    第5章 战略 5.1 认知 5.1.1 头脑风暴 5.1.2 规划 5.1.3 监控 5.1.4 沟通 5.2 个体过程 5.2.1 卓越的承诺 5.2.2 良性的纪律 5.2.3 效力和坚持 5.3 杠杆 5.3.1 自动化 5.3.2 警报系统 5.3.3 经验和专业知识 5.4 小结 ...

    J2EE应用开发详解

    57 4.3.8 Filter 58 4.4 使用Servlet处理客户端请求 58 4.5 会话跟踪 61 4.5.1 使用Cookie进行会话跟踪 61 4.5.2 使用URL重写进行会话跟踪 62 4.5.3 使用隐藏表单域进行会话跟踪 63 4.6 小结 65 第5章 JSP技术 67 ...

    《.NET最佳实践》.((美)Stephen Ritchie)

    第5章 战略 60 5.1 认知 62 5.1.1 头脑风暴 62 5.1.2 规划 63 5.1.3 监控 64 5.1.4 沟通 64 5.2 个体过程 66 5.2.1 卓越的承诺 67 5.2.2 良性的纪律 67 5.2.3 效力和坚持 68 5.3 杠杆 69 5.3.1 自动化 ...

    WSI v5.1.25 -php注入工具

    比如第4个数字会在页面上显示,那么你就将数字4替换成“loveuk”,而且最后不要跟注释符(因为程序会在提交的时候默认会自动加上),最终的url如下: http://127.0.0.1/x.php?id=10 and 1=2 union select 1,2,loveuk,...

    ASP.NET Night Words

    第5章 page类和回调技术 46 5.1 page类介绍 46 5.1.1 单文件页模型 46 5.1.2 代码隐藏页模型 48 5.2 asp.net页面的生命周期 50 5.3 利用page的事件进行统一 5.3 身份验证 52 5.4 ispostback属性 54 5.5 ...

    Java Web程序设计教程

    第5章struts2框架基础 80 5.1mvc框架 80 5.1.1model1与model2 80 5.1.2mvc设计模式 81 5.1.3struts2框架的mvc架构 82 5.2struts2概览 84 5.2.1struts2的工作流程 84 5.2.2struts2的简单应用 85 5.3struts2...

Global site tag (gtag.js) - Google Analytics