IOC
Bean创建默认是单例模式,只会创建一个bean对象。通过xml方式实现bean,其实就是通过反射来实现的,bean的创建先获取到类的Class对象默认通过无参构造进行对象的创建,然后再setter方法进行属性配置。把bean创建在容器当中
bean的使用ApplicationContext解析xml文件获取到Spring容器,此时bean对象已经创建好了,然后context.getbean()就可以拿到bean对象,就可以使用。
如果是有参构造,则通过<constructor-arg>去设置值
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
https://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="user" class="com.ioc.User">
<constructor-arg index="0" value="李四"></constructor-arg>
<constructor-arg name="name" value="lisi"></constructor-arg>
</bean>
</beans>
spring的配置
bean的自动装配
使用注解的自动装配
@Autowired:先通过byType,再byName
@Resource:先byName,再byType
Spring注解开发
AOP
代理模式,AOP的底层
代理模式的分类:静态代理和动态代理
静态代理
例子一
这是租房子的动作。
package com.ioc.Proxy;
//这是出租房子的动作
public interface Rent {
public void rent();
}
房东要出租房子,但是不想管其他的,就想交出钥匙和拿到房租
package com.ioc.Proxy;
//我这是房东,要出租房子
public class Host implements Rent{
@Override
public void rent() {
System.out.println("我是房东,我要出租房子");
}
}
代理对象来帮房东把房子租出去,并且把业务办好
package com.ioc.Proxy;
//我是中介,我要帮房东出租房子,并且扩展业务
public class Proxy implements Rent{
private Host host;
public Proxy(Host host){
this.host=host;
}
@Override
public void rent() {
System.out.println("中介带我看房子");
host.rent();
System.out.println("中介带我签合同");
}
}
我本来可以直接找房东,但是房东只想出租,所以我找代理让他带我租房子签合同
package com.ioc.Proxy;
//这是我,我要找中介去找房子住
public class Myself {
public static void main(String[] args) {
Host host = new Host();
Proxy proxy = new Proxy(host);
proxy.rent();
System.out.println("我找中介拿到了房子");
}
}
例子二
对数据库的操作
package com.ioc.DBOP;
//对数据库的操作
public interface mapper {
public void add();
public void delete();
public void update();
public void query();
}
服务层实现接口,对数据库进行操作
package com.ioc.DBOP;
//服务操作数据库
public class Service implements mapper{
@Override
public void add() {
System.out.println("新增了数据");
}
@Override
public void delete() {
System.out.println("删除了数据");
}
@Override
public void update() {
System.out.println("更新了数据");
}
@Override
public void query() {
System.out.println("查询了数据");
}
}
这是代理,因为要输出日志,所以我来帮服务层操作数据库并且加入日志
package com.ioc.DBOP;
//现在我要在操作之后加入日志
public class Proxy implements mapper{
private Service service;
public void setService(Service service) {
this.service = service;
}
@Override
public void add() {
service.add();
System.out.println("我是代理,我加入增加日志");
}
@Override
public void delete() {
service.delete();
System.out.println("我是代理,我加入删除日志");
}
@Override
public void update() {
service.update();
System.out.println("我是代理,我加入更改日志");
}
@Override
public void query() {
service.query();
System.out.println("我是代理,我加入查询日志");
}
}
这是我,我在操作数据库的时候直接找服务去操作,但是我还想打印日志,所以我找代理
package com.ioc.DBOP;
//我要去操作数据库,并且还要日志记录,我要去找代理给我打印日志
public class Myself {
public static void main(String[] args) {
Service service = new Service();
Proxy proxy = new Proxy();
proxy.setService(service);
proxy.add();
proxy.delete();
proxy.update();
proxy.query();
}
}
动态代理(基于接口,基于类)
改写例子一
租房的动作
package com.ioc.Proxy;
//这是出租房子的动作
public interface Rent {
public void rent();
}
房东想要把房子出租出去
package com.ioc.Proxy;
//我这是房东,要出租房子
public class Host implements Rent{
@Override
public void rent() {
System.out.println("我是房东,我要出租房子");
}
}
这是动态代理程序 ,getProxy()得到代理类,即得到中介,invoke()就是中介进行帮房东出租房子,并且进行功能增强。
package com.ioc.Proxy;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
//这个类自动生成代理类!!是一个处理程序
public class ProxyInvocationHandler implements InvocationHandler {
private Rent rent;
public void setRent(Rent rent) {
this.rent = rent;
}
//生成得到代理类
public Object getProxy(){
return Proxy.newProxyInstance(this.getClass().getClassLoader(),rent.getClass().getInterfaces(),this);
}
//处理代理实例,并返回结果
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("中介带我看房子");
//代理的本质就是反射
Object result = method.invoke(rent, args);
System.out.println("交钱");
return result;
}
}
这就是我,我首先要知道谁在出租房子,然后我要去找到代理房东的中介,通过invocationhandler处理程序动态得到中介,并跟中介进行交接处理。
package com.ioc.Proxy;
//这是我,我要找中介去找房子住
public class Myself {
public static void main(String[] args) {
//真实的角色
Host host = new Host();
//代理角色 :现在还没有
ProxyInvocationHandler pih = new ProxyInvocationHandler();
//通过程序来处理调用的接口对象
pih.setRent(host);
//返回代理类,动态生成
Rent proxy = (Rent) pih.getProxy();
proxy.rent();
System.out.println("我找中介拿到了房子");
}
}
改写例子二
Spring实现AOP
通过注解实现AOP
package com.ioc.aoptest;
//动作接口
public interface Service {
public void add();
public void delete();
public void update();
public void query();
}
package com.ioc.aoptest;
public class Serviceimimpl implements Service{
@Override
public void add() {
System.out.println("新增了数据");
}
@Override
public void delete() {
System.out.println("删除了数据");
}
@Override
public void update() {
System.out.println("更新了数据");
}
@Override
public void query() {
System.out.println("查询了数据");
}
}
通过注解实现前置,后置,环绕通知,定义一个切面类
package com.ioc.aoptest;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.stereotype.Component;
@Aspect //标注这个类是一个切面
public class AnnotationPointCut {
//前置通知
@Before("execution(* com.ioc.aoptest.Serviceimimpl.*(..))")
public void before(){
System.out.println("前置通知!!!!-----");
}
//后置通知
@After("execution(* com.ioc.aoptest.Serviceimimpl.*(..))")
public void after(){
System.out.println("后置通知!!!!-----");
}
@Around("execution(* com.ioc.aoptest.Serviceimimpl.*(..))")
public void around(ProceedingJoinPoint joinPoint) throws Throwable {
System.out.println("环绕前通知!!!!-----");
Object proceed = joinPoint.proceed();
System.out.println("环绕后通知!!!!-----");
}
}
注册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:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans
https://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/aop
https://www.springframework.org/schema/aop/spring-aop.xsd">
<bean id="service" class="com.ioc.aoptest.Serviceimimpl"></bean>
<bean id="log" class="com.ioc.log.Log"></bean>
<bean id="afterlog" class="com.ioc.log.AfterLog"></bean>
<bean id="annotationPointCut" class="com.ioc.aoptest.AnnotationPointCut"></bean>
<aop:aspectj-autoproxy></aop:aspectj-autoproxy>
</beans>
声明式事务