1、spring的两大核心部分
(1)aop:面向切面编程,扩展功能不是通过修改源代码实现!
(2)ioc:控制反转
2、spring介绍
spring是一个一站式框架,即它在JavaEE的三层架构中,每一层都提供了不同的解决技术
web层 ——> springMVC service层 ——> spring dao层 ——> spring的jdbcTemplate
3、IOC入门案例
(1)导入jar包,ioc入门测试,只需要导入beans、core、context,spEL这四个spring核心jar包,log4j也导入!!
(2)随便创建一个类,写一个方法:
package cn.melo.bean;
public class User {
public void hello(){
System.out.println("HelloWorld");
}
}
创建配置文件(建议放在src下,随意起名字):
beans.xml:
<?xml version="1.0" encoding="utf-8" ?>
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns="http://www.springframework.org/schema/beans"
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
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd">
<!--表示创建一个对象,id是唯一标识,class是全类名-->
<bean id="user" class="cn.melo.bean.User"></bean>
</beans>
测试代码:
package cn.melo.test;
import cn.melo.bean.User;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class test {
@Test
public void test1(){
//加载配置文件
ApplicationContext context = new
ClassPathXmlApplicationContext("beans.xml");
//创建对象
User user = (User)context.getBean("user");
System.out.println(user);
user.hello();
}
}
测试结果:
即通过配置文件创建对象成功!!!
4、Bean实例化的三种方式
(1)就是上面我们用的方式,用无参构造,前提就是类中必须要有无参构造!
(2)用静态工厂,定义一个工厂类,写一个静态方法,返回一个Bean对象,然后再配置文件中配置即可:
代码:
静态工厂:
package cn.melo.factory;
import cn.melo.bean.User;
public class UserStaticFactory {
public static User getUser(){
return new User();
}
}
配置文件:
<?xml version="1.0" encoding="utf-8" ?>
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns="http://www.springframework.org/schema/beans"
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
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd">
<!--用静态工厂创建对象-->
<bean id="user" class="cn.melo.factory.UserStaticFactory" factory-method="getUser"></bean>
</beans>
测试出来也可以成功创建对象!!!
(3)用实例工厂创建:
写一个工厂类,在工厂类中写一个普通方法,返回bean对象,在配置文件中配置即可!
配置文件:
工厂类:
package cn.melo.factory;
import cn.melo.bean.User;
public class UserFactory {
public User getUser(){
return new User();
}
}
5、bean标签中常用的属性:
(1)id:随意命名,保证唯一即可,用它来得到对象!
(2)class:你要创建对象的类的全类名!
(3)name:功能和id一样,但它可以包含特殊符号,id不可以!
(4)scope:有五个值,分别是:
A、默认值:singleton:创建单列对象;
B、prototype:创建多例对象;
以下三种,仅在Web相关的ApplicationContext中生效。:
C、request:创建对象放入request域中!
D、session:创建对象放入session域中!
E、globalsession:创建对象放入globalsession中(application);
6、属性注入(创建对象,给类中的属性设置值):
(1)一般情况下,属性的注入有三种方式:setter、有参构造和通过接口注入!
(2)spring中只支持前两种:
A、用有参构造注入,首先要提供带参构造:
类:
package cn.melo.bean;
public class Person {
private Integer pid;
private String pname;
public Person(Integer pid, String pname) {
this.pid = pid;
this.pname = pname;
}
public Person() {
}
@Override
public String toString() {
return "Person{" +
"pid=" + pid +
", pname='" + pname + '\'' +
'}';
}
}
配置文件:
测试代码:
//加载配置文件
ApplicationContext context = new
ClassPathXmlApplicationContext("beans.xml");
//创建对象
Person person = (Person)context.getBean("person1");
System.out.println(person);
结果:
B、通过setter注入,首先要提供setXxx方法;
类:
package cn.melo.bean;
public class Player {
private Integer pnum;
private String name;
public void setPnum(Integer pnum) {
this.pnum = pnum;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "Player{" +
"pnum=" + pnum +
", name='" + name + '\'' +
'}';
}
}
配置文件:
测试代码:
//加载配置文件
ApplicationContext context = new
ClassPathXmlApplicationContext("beans.xml");
//创建对象
Player player = (Player)context.getBean("player1");
System.out.println(player);
测试结果:
(3)注入对象类型属性,先配置要注入的对象,然后再注入:
比如在Player对象中注入一个Coach对象!
首先在Player中添加属性:
在配置文件中配置bean创建Coach对象并用ref属性注入
测试结果:
(4)P名称空间注入:
比如创建一个Player对象,注入值:
P名称空间注入走的其实也是set方法,所以首先要在类中提供set方法,
其次还要在xml中引入p名称空间的约束:
xmlns:p="http://www.springframework.org/schema/p"
创建对象,注入属性:
<bean id="player2" class="cn.melo.bean.Player" p:pnum="3" p:pname="James"
p:coach-ref="coach"></bean>
测试代码:
//加载配置文件
ApplicationContext context = new
ClassPathXmlApplicationContext("beans.xml");
//创建对象
Player player = (Player)context.getBean("player2");
System.out.println(player);
测试结果:
(5)注入复杂类型属性:
A、注入数组:
<property name="属性名">
<array>
<value>值1</value>
<value>值2</value>
...
</array>
</property>
B、注入List集合
<property name="属性名">
<list>
<value>值1</value>
<value>值2</value>
...
</list>
</property>
C、注入Map:
<property name="属性名">
<map>
<entry key="键1" value="值1"></entry>
<entry key="键2" value="值2"></entry>
...
</map>
</property>
D、注入Properties:
<property name="属性名">
<props>
<prop key="键1">值1</prop>
<prop key="键2">值2</prop>
...
</map>
</property>
7、IOC和DI的区别
(1)IOC:控制反转,把创建对象的步骤交给spring来完成!
(2)DI:依赖注入,向类中的属性设置值!
关系:依赖注入不能单独存在,需要IOC作为基础;
8、spring整合web的原理
spring整合web的原理
(1)把加载配置文件和创建对象的过程,都在服务器启动时完成!
(2)实现原理:服务器启动时,会为每个项目创建一个ServletContext对象,
所以在web.xml中配置一个监听器,监听到ServletContext创建时,让它加载spring配置文件创建对象,把创建的对象放入ServletContext域中!
9、spring注解开发
要用注解进行开发,除了前面导入的基本jar之外,还要导入aop的jar包:
要有下面这个约束:
(1)开启注解扫描:
<!--开启注解扫描,base-package:是要扫描的包
context:component是到包下去扫描类,属性,方法上的注解-->
<context:component-scan base-package="cn.melo"></context:component-scan>
<!--扫描属性上面的注解-->
<!--<context:annotation-config></context:annotation-config>-->
(2)注解创建对象:
类:
package cn.melo.bean;
import org.springframework.stereotype.Component;
@Component(value = "student") //等同于:<bean id="user" class="...">
public class Student {
public void love(){
System.out.println("Love Life,Love Java");
}
}
测试代码:
//加载配置文件
ApplicationContext context = new
ClassPathXmlApplicationContext("beans.xml");
//创建对象
Student student = (Student)context.getBean("student");
System.out.println(student);
student.love();
测试结果:
(3)创建对象的注解(加在类上,目前来说功能都是一致的):@Component(value=“xxx”),@Controller(value=“xxx”) ——> 控制层,@Service(value=“xxx”) ——> 业务层,@Repository(value=“xxx”) ——> 持久层
还可以在类上加上注解@Scope(vlaue=“xxx”)表示创建单例还是多例对象!
(4)注解注入属性(可以不用提供set方法)
注解注入基本数据类型用@value(value=“xxx”)
注解注入类的对象用@Autowired,或者是@Resource(name=“对象的id”);
比如有个需求,在service类中注入到类的对象:
Dao.java
import org.springframework.stereotype.Component;
@Component(value = "dao")
public class Dao {
public void add(){
System.out.println("add......");
}
}
Service.java
package cn.melo.service;
import cn.melo.dao.Dao;
import org.springframework.stereotype.Component;
@Component(value = "service")
public class Service {
@Autowired
private Dao dao;
public void service(){
System.out.println("service....");
dao.add();
}
}
测试代码:
@Test
public void test6(){
//加载配置文件
ApplicationContext context = new
ClassPathXmlApplicationContext("beans.xml");
//创建对象
Service service = (Service)context.getBean("service");
service.service();
}
测试结果:
换一种方式:
Service.java
ckage cn.melo.service;
import cn.melo.dao.Dao;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
@Component(value = "service")
public class Service {
@Resource(name = "dao")
private Dao dao;
public void service(){
System.out.println("service....");
dao.add();
}
}
测试结果也是一样的!!!!
10、AOP的介绍:
(1)AOP:面向切面(方面)编程,扩展功能不修改源代码实现
(2)AOP采取横向抽取机制,取代了传统纵向继承体系重复性代码
(3)AOP底层使用动态代理实现:
A、第一种情况,有接口情况,使用动态代理创建接口实现类代理对象
B、第二种情况,没有接口情况,使用动态代理创建类的子类代理对象
- Spring 的AOP 的底层用到两种代理机制:
- JDK 的动态代理:针对实现了接口的类产生代理.
- Cglib 的动态代理:针对没有实现接口的类产生代理. 应用的是底层的字节码增强的技术生成当前类
的子类对象.
11、AOP操作术语:
(1)Joinpoint(连接点):所谓连接点是指那些被拦截到的点。在spring 中,这些点指的是方法,因为spring 只支持方法类型的连接点.
简记:类中可以被增强的方法!
(2)Pointcut(切入点):所谓切入点是指我们要对哪些Joinpoint 进行拦截的定义.
(3)Advice(通知/增强):所谓通知是指拦截到Joinpoint 之后所要做的事情就是通知.通知分为前置通知,后置通知,异常通知,最终通知,环绕通知(切面要完成的功能)
(4)Introduction(引介):引介是一种特殊的通知在不修改类代码的前提下,Introduction 可以在运行期为类动态地添加一些方法或Field.
(5)Target(目标对象):代理的目标对象
(6)Weaving(织入):是指把增强应用到目标对象来创建新的代理对象的过程.
spring 采用动态代理织入,而AspectJ 采用编译期织入和类装在期织入
(7)Proxy(代理):一个类被AOP 织入增强后,就产生一个结果代理类
(8)Aspect(切面): 是切入点和通知(引介)的结合