java框架注入是创建对象吗_spring(1)(用spring控制创建对象的细节,创建和注入的方式)...

回顾:Struts与Hibernate可以做什么事?

Struts,

Mvc中控制层解决方案

可以进行请求数据自动封装、类型转换、文件上传、效验…

Hibernate,

持久层的解决方案;

可以做到,把对象保存到数据库,从数据库中取出的是对象。

Spring框架

传统的方式,对象创建都是写死的。关于对象创建细节:

1.对象数量:单例,多个

2.创建时间:

action 访问时候创建

service 启动时候创建

dao 启动时候创建

3.对象的依赖关系:service依赖 dao

spring简单来说,就是处理对象的创建的、以及对象的依赖关系!

组件/框架设计

侵入式设计:

引入了框架,对现有的类的结构有影响;即需要实现或继承某些特定类。

例如:Struts框架

非侵入式设计:

引入了框架,对现有的类结构没有影响。

例如:Hibernate框架/ Spring框架

Inversion on Control , 控制反转 IOC

对象的创建交给外部容器完成,这个就做控制反转.(一个类需要一个对象,不在本类中创建)

依赖注入,  dependency injection

处理对象的依赖关系(一个类需要一个对象,拿过来的过程)

IOC/DI区别:

控制反转,解决对象创建的问题 【对象创建交给别人】

依赖注入,在创建完对象后, 对象的关系的处理就是依赖注入 【通过set方法依赖注入】

AOP

面向切面编程,切面举例:事务、日志、权限;

Spring框架:

可以解决对象创建以及对象之间依赖关系的一种框架。

且可以和其他框架一起使用;Spring与Struts, Spring与hibernate

(起到整合(粘合)作用的一个框架)

Spring提供了一站式解决方案:

1) Spring Core spring的核心功能: IOC容器, 解决对象创建及依赖关系2) Spring Web Spring对web模块的支持。可以与struts整合,让struts的action创建交给springspring mvc模式3) Spring DAO Spring 对jdbc操作的支持 【JdbcTemplate模板工具类】4) Spring ORM spring对orm的支持:

既可以与hibernate整合,【session】

也可以使用spring的对hibernate操作的封装5)Spring AOP 切面编程6)SpringEE spring 对javaEE其他模块的支持

spring各个版本中:

在3.0以下的版本,源码有spring中相关的所有包【spring功能 +依赖包】 如2.5版本;

在3.0以上的版本,源码中只有spring的核心功能包【没有依赖包】

(如果要用依赖包,需要单独下载!)

开发步骤:

1) 源码, jar文件:spring-framework-3.2.5.RELEASE

commons-logging-1.1.3.jar 日志

spring-beans-3.2.5.RELEASE.jar bean节点

spring-context-3.2.5.RELEASE.jar spring上下文节点

spring-core-3.2.5.RELEASE.jar spring核心功能

spring-expression-3.2.5.RELEASE.jar spring表达式相关表

以上是必须引入的5个jar文件,在项目中可以用户库管理!

2) 核心配置文件: applicationContext.xml

Spring配置文件命名方式:

applicationContext.xml / bean.xml

配置约束可以参考文档:spring-framework-3.2.5.RELEASE\docs\spring-framework-reference\htmlsingle\index.html

8f900a89c6347c561fdf2122f13be562.png

961ddebeb323a10fe0623af514929fc1.png

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">

View Code

实例:

applicationContext.xml(有时候创建的对象称bean对象是因为spring都是通过配置bean标签来得到对象)

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">

测试类:

public classTest {//1. 通过工厂类得到IOC容器创建的对象

@Testpublic void testIOC() throwsException {//创建对象//User user = new User();//现在,把对象的创建交给spring的IOC容器

Resource resource = new ClassPathResource("cn/itcast/a_hello/applicationContext.xml");//创建容器对象(Bean的工厂), IOC容器 = 工厂类 + applicationContext.xml

BeanFactory factory = newXmlBeanFactory(resource);//得到容器创建的对象

User user = (User) factory.getBean("user");

System.out.println(user.getId());

}//2. (方便)直接得到IOC容器对象

@Testpublic void testAc() throwsException {//得到IOC容器对象

ApplicationContext ac = new ClassPathXmlApplicationContext("cn/itcast/a_hello/applicationContext.xml");//从容器中获取bean

User user = (User) ac.getBean("user");

System.out.println(user);

}}

spring控制对象创建的细节

applicationContext.xml配置参数的作用:

1) 对象创建数量: 单例/多例scope="singleton", 默认值, 即 默认是单例 【service/dao/工具类】scope="prototype", 多例; 【Action对象】2) 什么时候创建?

scope="prototype"在用到对象的时候,才创建对象。scope="singleton"在启动(容器初始化), 就已经创建了bean,且整个应用只有一个。(单例想延迟初始化可以配置lazy-init=true)3)是否延迟创建(该属性只是针对单例) lazy-init="false"(可不写)默认, 不延迟创建,即在启动时候就创建对象 lazy-init="true"延迟初始化, 在用到对象的时候才创建对象(只对单例有效)4) 创建对象之后,指定对象初始化/销毁时调用的方法。 init-method="init_user"【对应对象的init_user方法,在对象创建之后执行 】 destroy-method="destroy_user" 【在调用容器对象的destriy方法时候执行,(容器用实现类ClassPathXmlApplicationContext】

实例:

public classUser {private intid;privateString name;publicUser() {super();

System.out.println("------User对象创建------");

}public intgetId() {returnid;

}public void setId(intid) {this.id =id;

}publicString getName() {returnname;

}public voidsetName(String name) {this.name =name;

}public voidinit_user() {

System.out.println("创建对象之后,初始化");

}public voiddestroy_user() {

System.out.println("IOC容器销毁,user对象回收!");

}

配置:

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">

测试类:

public void testIOC() throwsException {//得到IOC容器对象 【用实现类,因为要调用销毁的方法】

ClassPathXmlApplicationContext ac = new ClassPathXmlApplicationContext("cn/itcast/a_hello/applicationContext.xml");

System.out.println("-----容器创建-----");//从容器中获取bean

User user1 = (User) ac.getBean("user");

User user2= (User) ac.getBean("user");

System.out.println(user1);

System.out.println(user2);//销毁容器对象 (ClassPathXmlApplicationContext类才有销毁方法)

ac.destroy();

}

spring实现创建对象的方式:

SpringIOC容器,是spring核心内容。

作用: 创建对象 & 处理对象的依赖关系

IOC容器创建对象: 有几种方式:

1) 调用无参数构造器

2) 带参数构造器

3) 工厂创建对象

工厂类,静态方法创建对象

工厂类,非静态方法创建对象

实例:

User.java

8f900a89c6347c561fdf2122f13be562.png

961ddebeb323a10fe0623af514929fc1.png

public classUser {private intid;privateString name;publicUser() {super();

System.out.println("------User对象创建【无参数构造器】------");

}public User(intid, String name) {

System.out.println("-----User对象创建【带参数构造器】--------");this.id =id;this.name =name;

}public intgetId() {returnid;

}public void setId(intid) {this.id =id;

}publicString getName() {returnname;

}public voidsetName(String name) {this.name =name;

}

@OverridepublicString toString() {return "User [id=" + id + ", name=" + name + "]";

}public voidinit_user() {

System.out.println("创建对象之后,初始化");

}public voiddestroy_user() {

System.out.println("IOC容器销毁,user对象回收!");

}

}

View Code

ObjectFactory.java

//工厂,创建对象

public classObjectFactory {//实例方法创建对象

publicUser getInstance() {return new User(100,"工厂:调用实例方法");

}//静态方法创建对象

public staticUser getStaticInstance() {return new User(101,"工厂:调用静态方法");

}

bean.xml(配置文件名字可以自定义,可以放在src下也可以在包下)

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">

测试类:

public void testIOC() throwsException {//创建IOC容器对象

ApplicationContext ac = new ClassPathXmlApplicationContext("cn/itcast/b_create_obj/bean.xml");//获取容器中的对象

User user = (User) ac.getBean("user");

System.out.println(user);

}

处理对象依赖关系,Spring给对象的属性赋值【DI, 依赖注入】

(对象依赖的数据存放在属性中,属性可以是对象和基本类型,而将这些数据赋值给这些属性的过程就是依赖注入)

注入的方式有:

1) 通过构造函数2) 通过set方法给属性注入值3) p名称空间4) 自动装配(了解)5) 注解

构造函数,set属性,p名称空间的方式实例:

User.java

8f900a89c6347c561fdf2122f13be562.png

961ddebeb323a10fe0623af514929fc1.png

public classUser {private intid;privateString name;//--> 通过容器注入属性值

public void setId(intid) {this.id =id;

}// //--> 通过容器注入属性值

public voidsetName(String name) {this.name =name;

}public intgetId() {returnid;

}publicString getName() {returnname;

}

@OverridepublicString toString() {return "User [id=" + id + ", name=" + name + "]";

}publicUser() {super();

System.out.println("------User对象创建【无参数构造器】------");

}public User(intid, String name) {

System.out.println("-----User对象创建【带参数构造器】--------");this.id =id;this.name =name;

}

View Code

UserAction.java

8f900a89c6347c561fdf2122f13be562.png

961ddebeb323a10fe0623af514929fc1.png

public classUserAction {//Service: springIOC容器注入

privateUserService userService;public voidsetUserService(UserService userService) {this.userService =userService;

}publicString execute() {

userService.save();return null;

}

View Code

UserDao.java

8f900a89c6347c561fdf2122f13be562.png

961ddebeb323a10fe0623af514929fc1.png

public classUserDao {public voidsave() {

System.out.println("DB:保存用户");

}

View Code

UserService.java

8f900a89c6347c561fdf2122f13be562.png

961ddebeb323a10fe0623af514929fc1.png

public classUserService {private UserDao userDao; //= new UserDao();//IOC:对象的创建交给spring的外部容器完成

public voidsetUserDao(UserDao userDao) {this.userDao =userDao;

}public voidsave() {

userDao.save();

}

View Code

bean.xml

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">

测试类:

public classApp {//创建容器对象

private ApplicationContext ac = new ClassPathXmlApplicationContext("cn/itcast/c_property/bean.xml");

@Testpublic voidtestSet() {//从容器中获取

User user = (User) ac.getBean("user");

System.out.println(user);

}

@Testpublic voidtestExecuteAction() {//从容器中获取Action

UserAction userAction = (UserAction) ac.getBean("userAction");

userAction.execute();

}}

bean_p.xml(采用命名空间的标签的方式,属性对象也需要set方法):

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">

测试类:

//创建容器对象

private ApplicationContext ac = new ClassPathXmlApplicationContext("cn/itcast/c_property/bean_p.xml");

@Testpublic voidtestExecuteAction() {//从容器中获取Action

UserAction userAction = (UserAction) ac.getBean("userAction");

userAction.execute();

System.out.println(ac.getBean("user"));

}

自动装配方式,分为:根据名称和类型自动装配(属性对象也需要set方法)

1.根据名称自动装配:autowire="byName"(自动去IOC容器(bean.xml配置)中找与属性名同名的引用的对象,并自动注入)

也可以定义到全局, 这样就不用每个bean节点都去写autowire=”byName”

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"default-autowire="byName">根据名称自动装配(全局)

2.根据类型自动装配:autowire="byType"(必须确保依赖的类型在IOC容器中只有一个配置;否则报错)

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"default-autowire="byType">

(一般不推荐使用)Spring提供的自动装配简化配置,但是不利于后期的维护。(应该是依赖关系的可读性比较差,需要从类中确定)

测试类:

8f900a89c6347c561fdf2122f13be562.png

961ddebeb323a10fe0623af514929fc1.png

//创建容器对象

private ApplicationContext ac =

new ClassPathXmlApplicationContext("cn/itcast/d_auto/bean.xml");

@Testpublic voidtestExecuteAction() {//从容器中获取Action

UserAction userAction = (UserAction) ac.getBean("userAction");

userAction.execute();

}

View Code

注解方式,简化spring的IOC容器的配置

(注解的方式,属性对象不用提供set方法)

使用注解步骤:

1)先引入context名称空间:xmlns:context="http://www.springframework.org/schema/context"

2)开启注解扫描:

3)代码中使用注解

代码中相关的注解:Component/Resource

@Component :指定把一个对象加入IOC容器(还可以这样写@Component(‘属性名’),意思加入并且取名为xxx)

@Repository 作用同@Component; 在持久层使用(这样写,好像只是增强了可读性,层次比较清晰)

@Service 作用同@Component; 在业务逻辑层使用

@Controller 作用同@Component; 在控制层使用

@Resource :属性注入,根据类型注入(还可以这样写@Resource(name="xxx")注入名为xxx的对象)

实例:

UserAction.java

8f900a89c6347c561fdf2122f13be562.png

961ddebeb323a10fe0623af514929fc1.png

//@Component("userAction")//加入IOC容器//@Component

@Controller //控制层的组件

public classUserAction {

@ResourceprivateUserService userService;publicString execute() {

userService.save();return null;

}

}

View Code

UserDao.java(注解被注释掉了,是为测试注解和bean配置共同使用的情况)

8f900a89c6347c561fdf2122f13be562.png

961ddebeb323a10fe0623af514929fc1.png

//把当前对象加入ioc容器//@Component("userDao")//相当于bean.xml 【】//@Component//加入ioc容器的UserDao对象的引用名称, 默认与类名一样, 且第一个字母小写//@Repository//在持久层可以选择用这个注解

public classUserDao {publicUserDao(){

System.out.println("UserDao.UserDao()");

}public UserDao(intid){

System.out.println("UserDao.UserDao(int id)" +id);

}public voidsave() {

System.out.println("DB:保存用户!!!");

}

}

View Code

UserService.java

//@Component("userService")//userService加入ioc容器//@Component

@Service //表示业务逻辑层的组件

public classUserService {//@Resource//根据类型查找 【在容器中要确保该类型只有一个变量,针对的是注解和配置bean一起使用的情况,如果都是采用注解,只会一个类型加入IOC容器】

@Resource(name = "userDao")//根据名称查找

private UserDao userDao; //去容器中招UserDao类型的变量,找到后就赋值

public voidsave() {

userDao.save();

}

}

bean.xml

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">

//注释掉了userDao中注解(注解和配置bean可以互补的方式共同使用)

测试类:

//创建容器对象

private ApplicationContext ac = new ClassPathXmlApplicationContext("cn/itcast/e_anno2/bean.xml");

@Testpublic voidtestExecuteAction() {//从容器中获取Action

UserAction userAction = (UserAction) ac.getBean("userAction");

userAction.execute();

}

总结:

一种更加简便的依赖注入方式,那就是注解加自动装配,加入容器的对象添加注解,依赖的对象注入交给自动装配的方式注入(这样依赖的属性对象不用写注解,但需要写set方法,因为交个自动装配的方式)

你可能感兴趣的:(java框架注入是创建对象吗)