Spring框架分两大部分 IoC+Aop
IoC:控制反转,(其实意思就是通过配置去新建一个对象,将对象的管理交给spring)
Aop:面向切面编程(通俗说就是在某个已经写好了的类方法里面加一个方法,这个方法可以在哪个类方法的前、后或者环绕)
上面这两个我自己说的比较简单,但是真的做起来还是有点抽象。希望练练吧。
作用:spring作为SSH框架的service层
与struts2整合的时,帮组Struts2创建action对象。也就是说spring在配置文件中(bean.xml)管理action对象的创建。
与hibernate整合时,将hibernate的核心配置有关数据库的配置文件放在spring配置文件中。然后帮助创建sessionFactory对象,这个解决的办法是需要在服务器启动的时候创建。
介绍Ioc和Aop,都是自己的理解和笔记:
IoC: 控制反转
IoC底层实现所需要的技术
1、 XML配置文件
2、dom4j解析XML
3、工厂设计模式
4、反射
首先使用工厂设计模式解耦合操作
过程: public class User{
public void add(){
}
}
class UserService{
User u = UserFactory.getUser();
u.add();
}
class UserFactory{
public static User getUser(){
return new user();
}
}
将他们进行分工,用三个类对其进行解耦合.。然后这种方法的耦合度还是比较高 存在 UserService和USerFactory之间的耦合。
然后是配置XML文件,创建一个对象类
<bean id = "User" class = "com.oa.User"> class里面是类路径
使用dom4j 解析XML文件 可以根据上面的id值去得到class属性值 String classValue = "class属性值"
使用反射创建类对象 Class clazz = Class.forName(classValue); //创建类对象
User user = clazz.newInstance(); return user;
怎么取加载XML文件并得到配置的对象
首先先在src下面新建一个bean.xml 文件
ApplicationContext context = new ClasspathXmApplicationContext("bean.xml"); //需要得到配置对象的类中先写上这句
User user = (User)Context.getBean("User"); //这里面写的是id值 bean.xml配置的id值
Ioc的bean管理 有两种方式 配置XML文件和注解
配置文件方式:
bean的三种实例化方式(XML)
Class User{
private String name;
public User(){}
public User(String name){
this.name=name;
}
public void add(){
}
}
1、使用类的无参构造(重点)常用
<bean id="user" class = "com.oa.User"> 这种配置就相当于 new User();
【注意要保证User类里面有无参构造】
ApplicationContext context =
new ClassPathXmlApplicationContext("bean.xml");
User user = (User) context.getBean("user");
user.play();
【注意导包不要导错了 都是spring的包】
2、静态工厂创建
就是再写一个静态方法,然后配置的时候要配置这个方法
<bean id="user" class = "com.oa.User" Factory-method="getBean">
public static bean getbean(){
return new Bean();
}
使用静态方法,返回类对象
3、使用实例化工厂创建
<bean id = "UserFactory" class = "com.oa.UserFactory">
<bean id="user" class = "com.oa.User" Factory-Bean = "UserFactory" Factory-method="getBean">
UserFactory 这个类里面有getBean()这个方法。
属性的注入 就是创建对象的时候设置属性的值)
以前有两种方法 带参数的构造方法和使用set方法
spring框架支持这两种 【注意开发中一般常用的是set方法】
有参构造注入属性: <bean id = "user" class = "com.oa.User">
<constructor-arg name = "name" value = "牛星宇"></constructor-arg>
</bean>
其中name指的是属性名 , value指的是自己设置的值。
set方法注入属性: <bean id = "user" class = "com.oa.User">
<property name="name" value="niuxingyu"></property>
</bean>
其中name指的是属性名 , value指的是自己设置的值。
注入对象类型的属性:
// 在开发中 dao层专门负责实现,然后service层负责调用dao里面的东西 所以需要注入对象。。
有两个类 UserService UserDao 在UserService中把UserDao作为属性注入
配置:
<bean id = "userdao" class = "com.oa.UserDao"></bean>
<bean id ="userservice" class = "com.oa.UserService">
<property name = "UserDao" ref = "userdao">
</bean>
name是对应得属性名,因为要传的是一个对象所以属性是一个类,然后ref是引用的意思,ref里面放的是对象配置的那个id值。
注入复杂类型:
注入数组: private String[] array;
注入list private List<String> list;
注入map private Map<String,String> map;
注入perporties private Perporties perporties;
【还是要set方法一样的注入,就是一些设置属性值不一样而已】
<bean id = "user" class = "com.oa.User">
<!---数组->
<property name = "array">
<list>
<value>老牛</value>
<value>牛儿子</value>
</list>
</property>
<!--list-->
<property name = "list">
<list>
<value>niulist</value>
<value>thelist</value>
</list>
</property>
<!--map-->
<property name = "map">
<map>
<entry key = "1" value = "apple"></entry>
<entry key = "2" value = "banana"></entry>
</map>
</property>
<!--properties-->
<property name = "map">
<props>
<prop key = "driver" >com.mysql.jdbc.driver</prop>
<prop key = "username" >root</prop>
</props>
</property>
</bean>
IoC注解方式:(代码里面的一些特殊标记)
【导入一个spring-aop jar包,引入一个约束spring-context,开发中常用的是注解方式】
首先在配置文件里面开启注解扫描,在包里面扫描 方法,类,属性上面的注解:
<context:component-scan base-package="com.oa"></context:component-scan>
base-package指的是需要扫描的包路径,多个包需要扫描的话 就直接在后面加“,”然后加包名。
注解创建对象:在对象的类上面加一个注解
@Component(value="user") = <bean id = "user" class = "com.oa.User">//value可以省略
@scope(value = "prototype") 代表创建的是单实例还是多实例
获取对象和之前是一样的。
还有几个注解:@controller web层 @Service 业务层 @Repository 持久层
一共四个注解的功能是一样的。但是可以在不同层使用不同的注解,其实也无所谓区分
注解配置属性:
1、在属性上面加一个@Autowired(自动装配)//所有属性都可以注入
2、在属性上加一个Resource(name = "userdao") //对于对象类型属性,name里面是对应类的注解value值
【这个没有1上面那个方便。但是用的比较多的是2,2比较准确】
关于配置文件和注解混合使用例子:有三个类 BookDao BookService OrdersDao
对于三个类对象的创建可以通过 spring配置文件
<bean id ="BookDao" class ="com.oa.BookDao"></bean>
<bean id ="BookService" class ="com.oa.BookService"></bean>
<bean id ="OrdersDao" class ="com.oa.OrdersDao"></bean>
目的是在OrdersDao里面添加 BookDao 、BookService类对象
在OrdersDao里面进行配置
@Resource(name="bookdDao")
private BookDao bookDao;
@Resource(name="bookSerrvice")
private BookService bookService;
配置既可。。。。。。
Aop :面向切面编程
作用:扩展功能且不修改源代码实现,Aop采用横向抽取机制,取代了传统的纵向继承体系重复性代码
纵向机制,是采用继承的方法,有一个新的子类,然后在子类中新的方法,然后继承父类里面的老方法。这样去扩展功能。
横向机制:底层实现是采用动态代理的方式实现。
第一种情况:针对接口与接口实现类,创建一个接口的实现类的代理对象
第二种情况:针对没有接口的情况 创建一个子类的代理对象
关于Aop的术语以及操作,配置和注解两种方式
连接点(Joinpoint): 可以被增强的方法
切入点(pointcut): 实际增强的方法(就是需要围绕这个方法前后写其他功能)
切面(aspect): 把增强应用到方法中,这一过程叫做切面
通知/增强(advice): 增强的逻辑
{
前置:在方法之前 后置:方法之后 异常:方法异常 最终:方法最后 环绕:方法前后
}
【关于Aop操作,需要到一个Aop约束 spring-Aop】
导入这些包
AspectJ 是一个面向切面的框架 它不是spring的一部分,只是一起完成Aop操作
基于AspectJ的XML配置
基于AspectJ的注解方式
XML配置:表达式配置切入点 execution(<访问修饰符>?<返回类型><方法名>(参数)<异常>)
比如:execution(*com.oa.Book.add(..)) *是通配符,是所有的意思。前面的包路径也可以用*表示
![](https://i-blog.csdnimg.cn/blog_migrate/68c00cb02345fc93df06b6321668e918.png)
Log4J介绍
日志,通常可以通过Log4J可以看到程序的更详细的信息。特别是在找bug的时候特别有用。
可以在Log4J看到对象的创建配置文件的加载。
关于里面的配置文件(log4j.perproties) 其中有一条 log4j.rootLogger = info,stdout
(其中 info代表查看级别,debug 的级别更高,info是查看基本的信息)
关于Ioc与DI的区别
IoC:控制反转,把对象的创建交给spring管理
DI:依赖注入,向类属性里面注入值
区别:依赖注入不能单独存在,需要在IoC基础之上完成。
Spring整合Web项目的原理
1、加载spring核心配置文件
以前是这样加载的 ApplicationContext context = new ClassPathXmlApplicationCotext();
【虽然这样可以加载,但是加载的速度比较慢,比较好的方式是在服务器启动的时候就加载好这个配置文件】
实现的原理:ServletContext 对象 监听器 (spring-web jar包才能监听)
实现的步骤:
在服务器启动的时候为每一个项目创建一个ServletContext对象
使用监听器监听ServletContext对象的创建 (这里的监听可以通过配置listener)
一旦监听到ServletContext对象的创建就立马去创建配置对象(ApplicationContext)
然后把创建的对象放在ServletContext对象中(setAttribute)
想要得到这个对象(getAttriute)
配置监听器: