spring

spring,第1张

spring

为什么要学习spring?

spring提供了ioc容器,不需要自己创建和管理对象,由spring来创建和管理。

spring提供了面向切面编程,不修改源代码的情况下对功能进行增强。

spring提供了事务支持,使事务 *** 作变得更加方便。

spring方便集成其他框架,例如mybatis。


IOC

控制反转,由spring来创建对象以及对象之间的调用。最主要的作用就是降低耦合度。

传统方式:

        class A{                                                                             class B{

                add(){                                                                                 put(){}

                        B b = new B();                                                     }

                        b.put();

                }

             }

工厂模式:

        

        class A{                                                                             class B{

                add(){                                                                                 put(){}

                       B b =Factory.getB()                                                   }

                        b.put();

                }

             }

  

           class  Factory{

                public static  B   getB(){

                        return new B();

                }

}

耦合度不可能不存在,只能是降低到最小。


IOC底层原理:

        ioc主要是由xml解析、工厂模式以及反射实现的。

        1.在xml文件里配置要创建的对象

       

        2.创建工厂类

        class  Factory{

                public static  B   getB(){

                        String classValue  =类路径   //这是由xml解析得到的

                        Class clazz  =Class.forName(classValue);  //反射机制,通过类名得到该类的字节码文件

                        return (强转)clazz.newInstance();  //newInstance()方法默认调用类的空参构造器创建对象

                }

ioc容器底层的本质就是对象工厂。


基于注解方式创建对象以及注入属性

创建对象的注解

@Component       普通组件

@Controller          用于web层

@Service              用于业务逻辑层

@Repository         用于持久层(数据层)

属性注入(对象类型的属性)

@AutoWired  (最常用)   根据属性类型自动注入

@Qualifier         根据属性名称注入,这个注解需要和@AutoWired 一起使用,当一个接口有多个实现类,仅@AutoWired无法确定是注入哪个实现类的对象,需要用 @Qualifier (value="类名小写")

@Resource      可以根据类型或名称注入

@AutoWired 和@Resource 的区别:

        @AutoWired默认按照属性类型注入,根据名称需要加@Qualifier 

        @Resource默认按照属性名称注入,名称找不到才会按照属性类型注入。


AOP

面向切面编程

底层原理(动态代理)

1.有接口情况,使用jdk动态代理

public interface UserDao {

    public int add(int a, int b);

    public String update(String id);
}
public class UserDaoImpl implements  UserDao{

    @Override
    public int add(int a, int b) {
        System.out.println("add方法执行了");
        return a+b;
    }

    @Override
    public String update(String id) {
        System.out.println("update方法执行了");
        return id;
    }
}

 创建代理对象需要用到Proxy类的newProxyInstance()方法,三个参数为类加载器,接口,InvocationHandler接口的实现类对象

public class JDKProxy {
    public static void main(String[] args) {

        Class[] interfaces = {UserDao.class};
        UserDaoImpl userDao = new UserDaoImpl();
        //接口等于实现类创建代理对象
        UserDao dao =(UserDao) Proxy.newProxyInstance(JDKProxy.class.getClassLoader(), interfaces, new UserDaoProxy(userDao));
        int result =  dao.add(1, 2);
        System.out.println("result"+result);

    }

}
//创建代理对象代码
class UserDaoProxy implements InvocationHandler {

    //把需要增强的方法所在的类的对象传递过来
    //通过有参构造传递
    private Object obj;
    public UserDaoProxy(Object obj) {
        this.obj = obj;
    }


    //增强的逻辑代码
    //proxy代表代理类,method是代理类和被代理的同名方法,args方法参数
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        //方法之前的增加处理
        System.out.println("方法之前执行"+method.getName()+":传递的参数.."+ Arrays.toString(args));

        //被增加的方法的执行
        Object res = method.invoke(obj, args);

        //方法之后的增加处理
        System.out.println("方法之后输出"+obj);
        return res;
    }
}

2.没有接口情况,使用cglib动态代理

public class UserDao {
	public void addUser() {
		System.out.println("添加方法");
	}
	
	public void deleteUser() {
		System.out.println("删除方法");
	}

}
public class CglibProxy implements MethodInterceptor{
	
	//创建代理方法
	public Object createProxy(Object object) {
		//创建一个动态类对象
		Enhancer enhancer = new Enhancer();
		
		//确定需要增强的类 设置其父类
		enhancer.setSuperclass(object.getClass());
		
		//添加回调函数
		enhancer.setCallback(this);
		
		//返回创建的代理类
		return enhancer.create();
	}

	//proxy cglib根据定义的父类生成的代理对象
	//method  拦截的方法
	//args  拦截的方法的参数数组
	//methProxy  方法的代理对象 用于执行父类的方法
	@Override
	public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methProxy) throws Throwable {
		
		//方法执行之前
		
		//目标方法执行
		Object obj = methProxy.invokeSuper(proxy, args);
		
		//方法执行之后
		return obj;
	}

}
public class CglibTest {
	public static void main(String[] args) {
		//创建代理对象
		CglibProxy cglibProxy = new CglibProxy(); 
		//创建目标对象
		UserDao userDao = new UserDao();
		//将目标对象传入代理对象中   获取增强后的方法
		UserDao userDao2 = (UserDao) cglibProxy.createProxy(userDao);
		//执行
		userDao2.addUser();
		userDao2.deleteUser();
	}

}


欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zaji/4021225.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-10-22
下一篇 2022-10-22

发表评论

登录后才能评论

评论列表(0条)

保存