spring

spring是一个轻量级非入侵的框架,控制反转(ioc)和面向切面(aop)是spring的核心
spring可以通过 maven中的spring web mvc导入
支持事务处理,对框架整合支持

spring七大模块

1、核心容器(Spring Core)

核心容器提供Spring框架的基础功能。Spring以bean的方式进行java应用的各大组件及关系的组织和管理。Spring使用BeanFactory来产生和管理bean,是工厂模式的实现。BeanFactory使用控制反转(IOC)模式来将应用的配置和依赖性规范与实际的应用程序代码分开。

2、应用上下文(Spring Context)

实现了ApplicationContext接口,Spring的上下文,拓展了核心容器,提供事件处理、国际化等功能。它还提供了一些企业级服务的功能,提供了JNDI、EJB、RMI的支持。

3、Spring面向切面编程(Spring AOP)

提供切面支持,是个轻量级的容器。Spring管理的任何对象都支持AOP,SpringAOP模块基于Spring的应用程序中的对象提供了事务管理服务,通过使用SpringAOP,就可以将声明性事务管理集成在应用程序中。

4、JDBC和DAO模块(Spring DAO)

提供对JDBC的支持,还提供了DAO的支持,提供事务支持。

JDBC、DAO的抽象层,提供了有意义的异常层次结构实现,可用该结构来管理异常处理,和不同数据库提供商抛出的错误信息,异常层次结构简化了错误处理,并且极大的降低了需要编写的代码数量,比如打开和关闭链接。

5、对象实体映射(Spring ORM)

ORM:Object Relational Mapping,指对象实体映射。Spring插入了若干个ORM框架,提供了ORM对象的关系工具,其中包括Hibernate,JDO和IBatisSQL Map等,所有这些都遵从Spring的通用事务和DAO异常层次结构。

6、Web模块(Spring Web)

拓展了Spring上下文,提供Web应用上下文,对Web开发提供功能上的支持,如请求、表单、异常等。

7、MVC模块(SpringWebMVC)

MVC框架是一个全功能的构建Web应用程序的MVC实现,通过策略接口,MVC框架编程高度可配置的,MVC容纳了大量视图技术,其中包括JSP,POI等,模型由JavaBean来构成,存放于m当中,而视图是一个接口,负责实现模型,控制器表示逻辑代码,由c的事情。

spring框架的功能可以用在任何J2EE服务器当中,大多数功能也适用于不受管理的环境,spring的核心要点就是支持不绑定到特定J2EE服务的可重用业务和数据的访问对象,毫无疑问这样的对象可以在不同的J2EE环境,独立应用程序和测试环境之间重用。

ioc

id为bean的姓名 class为控制反转的全全限定名
property可以调用javabean中的set方法

1
2
3
<bean id="userServer" class="server.UserDaoImpli">
<property name="user" ref="userVip"/>
</bean>

怎么实现控制反转有参构造

1.下标赋值:

1
在<bean>中输入<constructor-arg index="" value="">

2.参数类型匹配

1
<constructor-arg type="" value="">会根据你的有参类型赋值,如果有多个参数相同会根据顺序赋值

3.通过参数名称赋值

1
<constructor-arg name="" value="">

额外知识:在配置文件被执行时对应的javabean就会被实例化

导入spring核心beans.xml在配置上下文

默认spring的控制反转前提是javabean有无参构造

在容器(beans.xml)在加载的时候对象就已经初始化了

1
2
3
4
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("beans.xml");
UserDaoImpli userServer = (UserDaoImpli) applicationContext.getBean("userServer");
UserDaoImpli userDaoImpli=(UserDaoImpli) applicationContext.getBean("userServer");
System.out.println(userDaoImpli==userServer);

其他配置

1.别名alias

1
<alias name="userVip" alias="userVip2"/>

起别名也可以在bean标签中的name属性中设置

1
<bean id="" class="" name=""> 

2.import可以将多个配置文件导入合并为一个

1
<import resource="bean.xml"/>

依赖注入(DI)

set注入

1.一般类型注入

1
<property name="name" value="冯越"/>

2.对象注入

1
<property name="name" ref=""/>

3.数组注入

1
2
3
4
5
6
7
8
<property name="books">
<list>
<value>红楼梦</value>
<value>西游记</value>
<value>水浒传</value>
<value>三国演义</value>
</list>
</property>

4.map注入

1
2
3
4
5
6
    <property name="card">
<map>
<entry key="身份证" value="361030200403091718"/>
<entry key="学生号" value="322031608"/>
</map>
</property>

5.set

1
2
3
4
5
6
<property name="games">
<set>
<value>LOL</value>
<value>Minecraft</value>
</set>
</property>

6.列表注入

1
2
3
4
5
6
7
8
<property name="books">
<list>
<value>红楼梦</value>
<value>西游记</value>
<value>水浒传</value>
<value>三国演义</value>
</list>
</property>

7.空

1
2
3
<property name="wife">
<null/>
</property>

8.Properties

1
2
3
4
5
<property name="info">
<props>
<prop key="user">root</prop>
</props>
</property>

c命令与p命令

在xml文件上方添加

1
2
3
4
xmlns:p="http://www.springframework.org/schema/p"
xmlns:c="http://www.springframework.org/schema/c"
<bean id="getName" class="pojo.Student" p:name="冯越">
<bean id="getName" class="pojo.Student" c:name="冯越" c:age=18>

p表示property,c表示construct(有参构造器)

bean的作用域

singleton 单例模式(默认)

共享对象 同一个bean造出来的对象相等

1
<bean id="getName" class="pojo.Student" scorpe="singleton">

prototype原型模式

独立对象 同一个bean造出来的对象会一样,每次getBean时都会产生新的对象

1
<bean id="getName" class="pojo.Student" scorpe="prototype">

其余session application request 只能在web开发中使用到

Bean的自动装配

spring会上下文自动寻找,并自动个bean装配属性
自动装配是spring满足bean依赖的一种方式

spring的三种装配的方式

1.在xml中显示的配置

2.在java中显示配置

不使用spring的xml配置,全权交给java
在Java中生成一个类,在类上面写@Configration
@Bean相当于xml写的一个bean而id就是方法名
这个方法的返回值相当于bean的class

1
2
3
4
5
6
7
8
9
@Configuration
@ComponentScan("pojo")
@import("")
public class Configfeng {
@Bean
public User getUser(){
return new User();//就是返回到注入bean的对象
}
}

@import相当于

1
<import resource="bean.xml"/>

3.隐式的自动装配

byName:会自动在容器上下文中查找,和自己对象set方法后面值对应的beanid id

1
<bean id="getName" autowire="byName">

byType:会自动在容器上下文中查找,和自己对象属性类型相同的bean,但必须类型全局唯一 class

1
<bean class="pojo.Student" autowire="byType">

byName时保证所有bean的id唯一,并且这个bean需要和自动注入属性的set方法保持一致
byType需要保证所有bean的对象类型唯一,并且这个bean需要和自动注入的属性类型一致

注解开发

导入约束:context约束
配置注解的支持:context:annotation-config/
指定要扫描的包

1
2
<context:component-scan base-package="com.kuang.pojo"/>
<context:annotation-config/>

@Component写在对应实体类上面
等价于

1
<bean id="userServer" class="server.UserServerImplement">

@Value(“冯越”)写在实体类对应属性上面或者写在set方法上面
等价于

1
<property name="user" ref="userDao"/>

@Component的衍生注解 功能都一样
在dao层@Repository
在server层@Service
在controller层@Controller

作用域注解
@Scorpe(“singleton”)

小结
xml配置:更加万能,适用于任何场合维护简单
注解:不是自己的类使用不了,维护复杂
xml用来管理bean
注解只负责完成属性的注入

Aop

代理模式

静态代理

角色分析:
抽象角色:一般会使用接口或者抽象类

真实角色:被代理的角色

代理角色:代理真实角色,代理真实角色后,我们一般会做一些附操作

客户:访问代理对象的人

代码举例:

抽象角色:出租

1
2
3
public interface Hire {
public void hire();
}

真实角色:房东

1
2
3
4
5
6
7
8
9
10
11
public class Host implements Hire{
private String name;
@Override
public void hire() {
System.out.println(name+"出租房屋了");
}

public void setName(String name) {
this.name = name;
}
}

代理角色:中介

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
public class Proxy implements Hire{
private Host host;
public Proxy(Host host) {
this.host = host;
}

@Override
public void hire() {
lookAround();
speak();
writePaper();
profitable();
host.hire();
}
private void lookAround(){
System.out.println("带你去看看房");
}
private void writePaper(){
System.out.println("签合同");
}
private void speak(){
System.out.println("谈判");
}
private void profitable(){
System.out.println("收钱");
}

}

客户:需要租房子的人

1
2
3
4
5
6
7
8
public class Client {
public static void main(String []arg){
Host host=new Host();
host.setName("冯越");
Proxy proxy=new Proxy(host);
proxy.hire();
}
}

Aop的作用

一般业务中是纵向开发流程也就是从dao-server-controller-前端但是业务大时要对业务修改又不能破坏原有代码哪就要用到我们的横向开发也就是AOP

代理模式的好与坏

好处

1.可以使真实角色的操作更加纯粹!不用去关注一些公用的业务

2.公共就交给代理角色!实现了业务的分工

3.公共业发生扩展的时候,方便集中管理!

缺点:

1.一个真实角色就会产生一个代理角色,代码量会翻倍,开发效率也会遍地

动态代理

动态代理和静态代理角色一样,但动态代理可以弥补静态代理中的缺点,
额,一下代码相当于中介

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
public class ProxyInvocationHandler implements InvocationHandler {
private Object target;
public void setHire(Object target){
this.target=target;
}
public Object getProxy(){
return Proxy.newProxyInstance(this.getClass().getClassLoader(),target.getClass().getInterfaces(),this);
}

@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
log(method.getName());
Object result=method.invoke(target,args);
return result;
}
public void log(String msg){
System.out.println("你调用了"+msg+"方法");
}
}

接下来是客户

1
2
3
4
5
6
Host host=new Host();
host.setName("冯越");
ProxyInvocationHandler proxy = new ProxyInvocationHandler();
proxy.setHire(host);
Hire proxy1 = (Hire) proxy.getProxy();
proxy1.hire();

动态太难了,直接学aop

Aop的实现

1.用spring接口实现Aop

导入依赖

1
2
3
4
5
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.8.7</version>
</dependency>

运行后的方法

1
2
3
4
5
6
public class log implements MethodBeforeAdvice{
@Override //method
public void before(Method method, Object[] args, Object target) throws Throwable {
System.out.println(target.getClass().getName()+" is "+method.getName());
}
}

运行前的方法

1
2
3
4
5
6
public class After implements AfterReturningAdvice {
@Override
public void afterReturning(Object returnValue, Method method, Object[] args, Object target) throws Throwable {
System.out.println("have begin "+method.getName()+" response is "+returnValue);
}
}

编写配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<?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"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd">
<bean id="userServer" class="user.UserServerImplement"/>
<bean id="beforeLog" class="log.log"/>
<bean id="after" class="log.After"/>
<aop:config>
<aop:pointcut id="poingcut" expression="execution(* user.UserServerImplement.*(..))"/>
<aop:advisor advice-ref="after" pointcut-ref="poingcut"/>
<aop:advisor advice-ref="beforeLog" pointcut-ref="poingcut"/>
</aop:config>
</beans>

测试(用接口接收)

1
2
3
4
5
6
7
public class Text {
public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext("applicationConfig.xml");
UserServer userServer = context.getBean("userServer", UserServer.class);
userServer.add();
}
}

2.自定义切面

配置:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<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"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd">
<bean id="userServer" class="user.UserServerImplement"/>
<bean id="beforeLog" class="log.log"/>
<bean id="after" class="log.After"/>
<aop:config>
<aop:pointcut id="poingcut" expression="execution(* user.UserServerImplement.*(..))"/>
<aop:advisor advice-ref="after" pointcut-ref="poingcut"/>
<aop:advisor advice-ref="beforeLog" pointcut-ref="poingcut"/>
</aop:config>
</beans>

写自定义的切面

1
2
3
4
5
6
7
8
public class point {
public void before(){
System.out.println("=======before=======");
}
public void after(){
System.out.println("=======after=======");
}
}

实现

1
2
3
4
5
6
7
public class Text {
public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext("applicationSelfConfig.xml");
UserServer userServer = context.getBean("userServer", UserServer.class);
userServer.add();
}
}

3.注解实现Aop

@Aspect 标记一个类为切面
@Befor(expression=”execution(* user.UserServerImplement.(..))”)写在方法执行前上面
@After(expression=”execution(
user.UserServerImplement.*(..))”)写在方法执行后上面

1
2
3
4
5
6
7
@Around("execution(* user.UserServerImplement.*(..))")
public void around(ProceedingJoinPoint jp) throws Throwable {
System.out.println("环绕前");
Signature signature = jp.getSignature();
Object proceed = jp.proceed();
System.out.println("环绕后");
}

配置信息

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<?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"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd">
<bean id="userServer" class="user.UserServerImplement"/>
<bean id="annotation" class="AnnotationAop.Annotation"/>
<aop:aspectj-autoproxy/>

</beans>

合并mybatis