{"id":1802,"date":"2021-04-10T12:17:03","date_gmt":"2021-04-10T12:17:03","guid":{"rendered":"https:\/\/gauravw.com\/blog\/?p=1802"},"modified":"2021-04-10T12:17:06","modified_gmt":"2021-04-10T12:17:06","slug":"spring-framework","status":"publish","type":"post","link":"https:\/\/gauravw.com\/blog\/2021\/04\/spring-framework\/","title":{"rendered":"Spring Framework"},"content":{"rendered":"\n<h1 class=\"wp-block-heading\">Spring Core<\/h1>\n\n\n\n<figure class=\"wp-block-embed\"><div class=\"wp-block-embed__wrapper\">\nhttps:\/\/medium.com\/omarelgabrys-blog\/spring-a-head-start-beans-configuration-part-2-4a8c239b070a#:~:text=%F0%9F%94%A6%20Java%20Annotations%20Vs%20XML,override%20that%20of%20the%20annotations.\n<\/div><\/figure>\n\n\n\n<p>Spring has many parts. Core is about dependency injection \/version where we have to decouple the classes.<\/p>\n\n\n\n<p>Spring has containers just like a Tomcat has called a container. It manages the lifecycle of an object mentioned in XML similar to Tomcat.<\/p>\n\n\n\n<p>This works based on Factory Pattern &#8211; A factory class can instantiate all the objects.<\/p>\n\n\n\n<p>So if you ask for an Object to Spring Bean Factory &#8211; it will give you that particular object.<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/lh3.googleusercontent.com\/VM-wiulxP7iLUy7GDXVzajM2K4zWa9WjgBhUfHbkapwx07uiA4wmuarDeqJuXPj9SMzk9g992xf1nSwMORqmwaAJibCg-a1N1gjH5wJFYUVdtGTMoawpGccmJ4UKHwc0rpViTbUP\" alt=\"\"\/><\/figure>\n\n\n\n<p>&lt;xml &gt;<\/p>\n\n\n\n<p>&lt;DocType ..<br>&lt;bean id=\u201d class=\u201d\u201d \/&gt;<br><br><\/p>\n\n\n\n<ol class=\"wp-block-list\"><li>XmlBeanFactory factory = new XmlBeanFactory (new ClassPathResource(&#8220;Beans.xml&#8221;));<\/li><\/ol>\n\n\n\n<p>2. BeanFactory factory = new ClassPathXmlApplicationContext(&#8220;spring.xml&#8221;);&nbsp;<br>Triangle triangle = (Triangle) factory.getBean(&#8220;triangle&#8221;);<br><br>Now if the triangle class was very complicated which required multiple other classes the bean def would change accordingly. The advantage is that you can get the Triangle class with just one statement instead of defining several of its dependencies every time the class is instantiated at multiple places.<\/p>\n\n\n\n<p><br>You can also use ApplicationContext instead of BeanFactory<br>The <strong>ApplicationContext<\/strong> interface is built on top of the <strong>BeanFactory<\/strong> interface. It adds some extra functionality such as simple integration with Spring&#8217;s AOP, message resource handling (for I18N), event propagation, application layer specific context (e.g. WebApplicationContext) for web application, annotation based dependency .<br><\/p>\n\n\n\n<p>BeanFactory uses lazy initialization <strong>but<\/strong> ApplicationContext uses eager initialization.&nbsp;<\/p>\n\n\n\n<p>However, to lazy load a bean via ApplicationContext once can use lazy-init=\u201dtrue\u201d in bean definition.<\/p>\n\n\n\n<p>Note : only singletons have the concept of lazy and eager loading, prototype are always made on request basis so they are loaded on request (lazily only).<\/p>\n\n\n\n<p>For Java class based configuration<\/p>\n\n\n\n<p>ApplicationContext ctx = new AnnotationConfigApplicationContext(HelloWorldConfig.class);<br>&nbsp;<\/p>\n\n\n\n<p>HelloWorldConfig class willl @Configuration over it<\/p>\n\n\n\n<p>@Import(HelloWorldConfig2.class)<\/p>\n\n\n\n<p>HelloWorldConfig2 configuration class is imported into HelloWorldConfig&nbsp;<\/p>\n\n\n\n<p>The above two methods are for setter injection. &lt;property name=\u201d\u201d value=\u201d\u201d&gt;<\/p>\n\n\n\n<p>Constructor based injection<\/p>\n\n\n\n<p>We can inject using constructor for the class.<br>&lt;bean..&gt;<\/p>\n\n\n\n<p>&nbsp;&lt;<strong>constructor-arg<\/strong> value\u201d\u201d<em> type=\u201d\u201d index=\u201d\u201d<\/em>&gt;<\/p>\n\n\n\n<p>&lt;\/bean&gt;<\/p>\n\n\n\n<p>Type and index r optional<\/p>\n\n\n\n<p><em>Type <\/em>defines type of class of argument &#8211; java.lang.String &#8211; to be used to explicitly say that this argument is of type String<br><em>Index <\/em>&#8211; position of argument &#8211; to be used if multiple String args etc are there<\/p>\n\n\n\n<p>Refer objects in a class\/ Injection Objects<\/p>\n\n\n\n<p>If a class has member variables as objects &#8211; they will be defined in spring.xml and can be used as<\/p>\n\n\n\n<p>&lt;bean \u2026&gt;<\/p>\n\n\n\n<p>&lt;property name=\u201d\u201d ref=\u201d&lt;ref bean id here&gt;\u201d \/&gt; (instead of value we use ref to refer another bean)<\/p>\n\n\n\n<p>&lt;\/bean&gt;<\/p>\n\n\n\n<p><strong>Idref vs ref<\/strong><\/p>\n\n\n\n<p>&lt;bean class=&#8221;A&#8221; id=&#8221;a&#8221; \/&gt;&nbsp;<\/p>\n\n\n\n<p>&lt;bean class=&#8221;B&#8221;\/&gt;<br>&lt;constructor-arg&gt;<br>&lt;ref bean=&#8221;a&#8221;\/&gt;<br>&lt;idref bean=&#8221;a&#8221;\/&gt;<br>&lt;\/constructor-arg&gt;<br>&lt;\/bean&gt;<\/p>\n\n\n\n<p>public B(A a, String string) {<br>string.equals(&#8220;a&#8221;); \/\/true<br>}<\/p>\n\n\n\n<p>So with ref you can <strong>reference an object<\/strong> and with idref you just reference the <strong>name of the bean<\/strong><\/p>\n\n\n\n<p>For idref one could have used direct string property<\/p>\n\n\n\n<p>&lt;constructor-arg type = &#8220;java.lang.String&#8221; value = &#8220;Zara&#8221;\/&gt;<\/p>\n\n\n\n<p>But if you use idref it&nbsp; ensures at deployment time that bean with that name exists otherwise it will throw error.&nbsp;<\/p>\n\n\n\n<p>InnerBean<\/p>\n\n\n\n<p>&lt;bean \u2026&gt;<\/p>\n\n\n\n<p>&lt;property name=\u201d\u201d &gt;<\/p>\n\n\n\n<p><strong>&lt;bean class = \u201c\u201d &gt;&lt;\/bean&gt;<\/strong><\/p>\n\n\n\n<p>&lt;\/property&gt;<\/p>\n\n\n\n<p>&lt;\/bean&gt;<\/p>\n\n\n\n<p>Alias<\/p>\n\n\n\n<p><strong>&lt;alias name \u201c&lt;bean id&gt;\u201d&nbsp; alias\u201d\u201d\/&gt;<\/strong><\/p>\n\n\n\n<p>Initializing collection Objects<\/p>\n\n\n\n<p>For string values<\/p>\n\n\n\n<p>&lt;property name = &#8220;addressList&#8221;&gt;<br>&nbsp; &nbsp; &nbsp; &nbsp; &lt;list&gt; -&gt; could also be &lt;set&gt; \/ &lt;map&gt;<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;value&gt;INDIA&lt;\/value&gt;<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;value&gt;Pakistan&lt;\/value&gt;<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;value&gt;USA&lt;\/value&gt;<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;value&gt;USA&lt;\/value&gt;<br>&nbsp; &nbsp; &nbsp; &nbsp; &lt;\/list&gt;<br>&nbsp; &nbsp; &nbsp; &lt;\/property&gt;<\/p>\n\n\n\n<p>For map<\/p>\n\n\n\n<p>&lt;map&gt;<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;entry key = &#8220;1&#8221; value = &#8220;INDIA&#8221;\/&gt;<\/p>\n\n\n\n<p>&lt;\/map&gt;<\/p>\n\n\n\n<p>For objects<\/p>\n\n\n\n<p>&lt;bean&gt;<\/p>\n\n\n\n<p>&lt;property name=\u201d\u201d &gt;<\/p>\n\n\n\n<p>&lt;list&gt;<\/p>\n\n\n\n<p><strong>&lt;ref&nbsp; bean =\u201d\u201d&gt;<\/strong><\/p>\n\n\n\n<p>&lt;ref&nbsp; bean =\u201d\u201d&gt;<\/p>\n\n\n\n<p>&lt;\/list&gt;<\/p>\n\n\n\n<p>&lt;\/property&gt;<\/p>\n\n\n\n<p>&lt;\/bean&gt;<\/p>\n\n\n\n<p>Injecting null values<\/p>\n\n\n\n<p>&lt;property name = &#8220;email&#8221;&gt;&lt;null\/&gt;&lt;\/property&gt;<\/p>\n\n\n\n<p>Types of bean scope<\/p>\n\n\n\n<ol class=\"wp-block-list\"><li>Singleton &#8211; one object of a bean per spring container<\/li><li>Prototype &#8211; multiple objects of bean per spring container &#8211; default<\/li><li>Global &#8211; one object per HTTP application. [MVC]<\/li><li>Session &#8211; one object per HTTP session. [MVC]<\/li><li>Request &#8211; one object per HTTP Request[MVC]<\/li><\/ol>\n\n\n\n<p>&lt;bean id=\u201d\u201d type =\u201d\u201d <strong>scope<\/strong>=\u201d\u201d&gt;<\/p>\n\n\n\n<p><strong>Interfaces which class can implement to get information<\/strong><\/p>\n\n\n\n<p>ApplicationContextAware<\/p>\n\n\n\n<p>MYclass implements ApplicationContextAware<\/p>\n\n\n\n<p>@overrider<\/p>\n\n\n\n<p>Void setContext\u2026 (AC content ) {<\/p>\n\n\n\n<p>this.context = context;<\/p>\n\n\n\n<p>}<\/p>\n\n\n\n<p>This way you can fetch the context in the class, similar interfaces exist like BeanNameAware etc.<br><br>Note that in newer versions it may be better to use annotations, rather than implementing spring-specific interfaces. Now you can simply use:<\/p>\n\n\n\n<p>@Inject \/\/ or @Autowired<br>private ApplicationContext ctx;<\/p>\n\n\n\n<p>Bean Definition Inheritance<\/p>\n\n\n\n<p>Just like inheritance there is parent child relationship in bean definitions too.<\/p>\n\n\n\n<p>Two beans can be defined by that relationship. The child can override the properties of the parent if it defines the same properties again.<\/p>\n\n\n\n<p>&lt;bean id =type= <strong>abstract<\/strong>= <strong>parent<\/strong>=<\/p>\n\n\n\n<p>One could define a bean <em>abstract <\/em>or child of some bean using <em>parent<\/em>.<\/p>\n\n\n\n<p>Bean Definition Template<\/p>\n\n\n\n<p>You can create a Bean definition template, which can be used by other child bean definitions without putting much effort.&nbsp;<\/p>\n\n\n\n<p>&lt;bean id = &#8220;beanTeamplate&#8221; abstract = &#8220;true&#8221;&gt;<\/p>\n\n\n\n<p>Lifecycle Methods<\/p>\n\n\n\n<p>Called before initialization and destruction<\/p>\n\n\n\n<p>Can be called in Two ways for each bean<\/p>\n\n\n\n<ol class=\"wp-block-list\"><li>Implementing <strong>Initializingbean<\/strong>, <strong>DisposableBean \/ BeanPostProcessor<\/strong><\/li><li>Using xml to define<strong> init-method<\/strong>, <strong>destroy-method<\/strong> in bean definition<\/li><\/ol>\n\n\n\n<p>&lt;bean id = &#8220;helloWorld&#8221; class = &#8220;com.gaurav.HelloWorld&#8221;<br>&nbsp; &nbsp; &nbsp; init-method = &#8220;init&#8221; destroy-method = &#8220;destroy&#8221;&gt;<\/p>\n\n\n\n<p>On a global level &#8211; &lt;<strong>beans<\/strong> &gt; every bean will be searched for the <strong>default-init-method<\/strong>, <strong>default-destroy-method<\/strong><br><\/p>\n\n\n\n<p>In any of the methods above each bean will have a seperate method for initialization and destruction.<\/p>\n\n\n\n<p>Common method for Initialization for all beans can be given in the following manner.<\/p>\n\n\n\n<ol class=\"wp-block-list\"><li>Implement BeanPostProcessor<\/li><li>register it in spring.xml<\/li><\/ol>\n\n\n\n<p>The same method will execute for all beans<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/lh4.googleusercontent.com\/4-pAiza2Aha49OqH1r6uHiuxoy41xYIJADfh7fVsO0va0vedF2xanEAFLIegYcX6KsQuj6coWYAoefM8JpsPz-47NhgiFNY201tUj0iQvCe6INwK3oFrV2DTVsOIfZwjHHeqQo0n\" alt=\"\"\/><\/figure>\n\n\n\n<p>Property Substitution<\/p>\n\n\n\n<p>If you want to assign a value of a bean through properties file then it can be done by<\/p>\n\n\n\n<ol class=\"wp-block-list\"><li>Register PropertyPlacementHolderConfig in spring.xml<\/li><li>Inside it a property will have value as the location\/name of the properties file<\/li><\/ol>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;3.<\/p>\n\n\n\n<p>&lt;bean class=&#8221;org.springframework.beans.factory.config.PropertyPlaceholderConfigurer&#8221;<\/p>\n\n\n\n<p>&nbsp;&gt;<\/p>\n\n\n\n<p>&lt;property name=\u201d\u201d value = \u201c${property1.propertyA}\u201d&gt;<\/p>\n\n\n\n<p>\/\/ or give an entire properties file<\/p>\n\n\n\n<p>&lt;property name=&#8221;location&#8221;&gt;<br>&lt;value&gt;database.properties&lt;\/value&gt;<br>&lt;\/property&gt;<\/p>\n\n\n\n<p>The property file can be Used like this<br>&lt;property name=&#8221;driverClassName&#8221; value=&#8221;${jdbc.driverClassName}&#8221; \/&gt;<\/p>\n\n\n\n<p>To use the value in a bean file<\/p>\n\n\n\n<p>@Value( &#8220;${jdbc.url}&#8221; ) private String jdbcUrl;<\/p>\n\n\n\n<p>@Required &#8211; if a function need to be called at the time of initiation then it has to be annotated accordingly so that if it setter the attribute which will be accessed should not give NullPointerException<\/p>\n\n\n\n<p><br>@Required<\/p>\n\n\n\n<p>Void setValue( String a)<\/p>\n\n\n\n<p>The error will be thrown at applications start up.<\/p>\n\n\n\n<p>You need to add a postprocessor in spring.xml to use annotation.<\/p>\n\n\n\n<p>Also in case&nbsp; of<strong> optional dependency<\/strong> injection this can be used.<\/p>\n\n\n\n<p>public class FooService {<br><br>&nbsp; &nbsp; @Autowired(required = false)<br>&nbsp; &nbsp; private FooDAO dataAccessor;<br>&nbsp; &nbsp;<br>}<\/p>\n\n\n\n<p>Else it can throw nosuchbeanfoundexception<\/p>\n\n\n\n<p><strong>Autowiring<\/strong><br>If you want bean injected automatically. Not constructor injection.<\/p>\n\n\n\n<p>Types<\/p>\n\n\n\n<p>Name &#8211; ids of all beans should be same as member variables<\/p>\n\n\n\n<p>Type &#8211; if there r member variables of different types. No two member variables should be of same type.<\/p>\n\n\n\n<p>@Autowired -. It will search for the <strong>type<\/strong> of this class in spring container , if it finds multiple entries then it searches for <strong>name<\/strong> match. If it doesn&#8217;t find then it fails.<\/p>\n\n\n\n<p><strong>Solving UnsatisfiedDependencyException with Spring autowiring<\/strong><\/p>\n\n\n\n<p>To overcome this problem there are <strong>two options<\/strong> &#8211;<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li><strong>primary candidate<\/strong> &#8211; Identify a primary candidate for auto wiring bean and set that as <strong>primary=&#8221;true&#8221;<\/strong><\/li><li>&lt;bean id=&#8221;payment&#8221; class=&#8221;org.netjs.springexp.prog.CashPayment&#8221; primary=&#8221;true&#8221;\/&gt;<\/li><li><strong>Exclude a bean from autowiring<\/strong> &#8211; You can exclude a bean from being autowired. For that set the <strong>autowire-candidate<\/strong> attribute of &lt;bean&gt; tag to false.<\/li><li>&lt;bean id=&#8221;creditPayment&#8221; class=&#8221;org.netjs.springexp.prog.CreditPayment&#8221; autowire-candidate=&#8221;false&#8221; \/&gt;<\/li><\/ul>\n\n\n\n<p>@Autowired over a constructor<\/p>\n\n\n\n<p>If there are more than one constructor in the class, only one constructor can have @Autowired annotation. This constructor should not be public.<\/p>\n\n\n\n<p>@Autowired with Field<\/p>\n\n\n\n<p>The class field can also be autowired using @Autowired annotation. Any number of fields can be autowired within a class. The fields which are autowired should not be public<\/p>\n\n\n\n<p>@Qualifier(\u201cqualifier\u201d) &#8211; this is used with @Autowired to specify which bean to autowire.<br>The same qualifier needs to given in bean definition in spring.xml<\/p>\n\n\n\n<p>@Autowired<br>&nbsp; @Qualifier(&#8220;student1&#8221;)<br>&nbsp; private Student student;<\/p>\n\n\n\n<p>JSR 250 Annotations<\/p>\n\n\n\n<p>@Resource &#8211; to inject based on the name same as @Autowired + @Qualifier used over functions.<\/p>\n\n\n\n<p>If you don&#8217;t want to use two annotations (the @Autowired and @Qualifier) you can use @Resource to combine these two.<\/p>\n\n\n\n<p>@Inject = @Autowired (@Inject is JSR specification, @Autowired is spring specific)<\/p>\n\n\n\n<p>&lt;bean id=&#8221;a&#8221; <strong>class<\/strong>=&#8221;org.sssit.A&#8221; autowire=&#8221;constructor&#8221;&gt;&lt;\/bean&gt;<\/p>\n\n\n\n<p>IF class has multiple constructors then by default the constructor with highest number of parameters is injected.<\/p>\n\n\n\n<p>&lt;bean id=&#8221;a&#8221; <strong>class<\/strong>=&#8221;org.sssit.A&#8221; autowire=&#8221;byName&#8221;&gt;&lt;\/bean&gt;&nbsp;<\/p>\n\n\n\n<p>If the properties of A name is not found &#8211; throws Exception<\/p>\n\n\n\n<p>&lt;bean id=&#8221;a&#8221; <strong>class<\/strong>=&#8221;org.sssit.A&#8221; autowire=&#8221;byType&#8221;&gt;&lt;\/bean&gt;&nbsp;<\/p>\n\n\n\n<p>IF multiple beans of same type found again throws Exception<\/p>\n\n\n\n<p>&lt;bean id=&#8221;a&#8221; <strong>class<\/strong>=&#8221;org.sssit.A&#8221; autowire=&#8221;no&#8221;&gt;&lt;\/bean&gt;<\/p>\n\n\n\n<p>@PostConstruct @PreDestroy &#8211; same as init and destroy methods.<\/p>\n\n\n\n<p>You need to add a post processor in spring.xml to use this annotation.<\/p>\n\n\n\n<p>One simple way to avoid all annotation related post processors is&nbsp; using<\/p>\n\n\n\n<p>&lt;context:annotation-config\/&gt;<\/p>\n\n\n\n<p><strong>@component <\/strong>&#8211; marks a class as a bean, it will auto instantiated with no mapping in spring.xml<\/p>\n\n\n\n<p>It will have name same as class with a small letter.<\/p>\n\n\n\n<p>&lt;context:component-scan: base-package=\u201d\u201d\/&gt; &#8211; scans these package to find @component, @Repository, @Controller annotations<\/p>\n\n\n\n<p>Message Source &#8211; Resource bundle<\/p>\n\n\n\n<p>Register a bean for the class ResourceBundleMessageSource along with resource bundles as a list<\/p>\n\n\n\n<p>&lt;bean id=&#8221;messageSource&#8221; class=&#8221;org.springframework.context.support.ResourceBundleMessageSource&#8221;&gt;<br>&lt;property name=&#8221;basename&#8221;&gt;<br>&lt;value&gt;locale\\customer\\messages&lt;\/value&gt;<br>&lt;\/property&gt;<br>&lt;\/bean&gt;<\/p>\n\n\n\n<p>The MessageSource object can be wired into any class to take this bean.<\/p>\n\n\n\n<p>messageSource.getMessage(&lt;property name&gt;, &lt;args to message&gt;, &lt;default message&gt;, &lt;locale&gt; );<\/p>\n\n\n\n<p>Listeners<\/p>\n\n\n\n<p>You can implement listeners which listen events<\/p>\n\n\n\n<p>Implementing ApplicationListener make a&nbsp; listener &#8211; which listens<\/p>\n\n\n\n<p>A class which has to be publish an event has to implement ApplicationEventPublishAware<\/p>\n\n\n\n<p>This class needs to have a setter for the publisher which the Spring will set from the application context.<\/p>\n\n\n\n<p>This publisher can publish the event.<\/p>\n\n\n\n<p><strong>context:component-scan<\/strong><strong><br><\/strong>Scans for all these <strong>annotations<\/strong><\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>@Component<\/li><li>@Repository<\/li><li>@Service<\/li><li>@Controller<\/li><\/ul>\n\n\n\n<p>One advantage of this element is that it also resolves @Autowired and @Qualifier annotations. Therefore if you declare &lt;context:component-scan&gt;, is not necessary anymore declare &lt;context:annotation-config&gt; too.<\/p>\n\n\n\n<p>Context:annotation-config &#8211; scans for Annotations only in already defined beans in XML file.<\/p>\n\n\n\n<p><strong>mvc:annotation-config<\/strong><\/p>\n\n\n\n<p>used for enabling the Spring MVC components with its default configurations.<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>Support for formatting Number fields with @NumberFormat<\/li><li>Support for formatting Date, Calendar, and Joda Time fields with @DateTimeFormat, if Joda Time is on the classpath<\/li><li>Support for validating @Controller inputs with @Valid, if a JSR-303 Provider is on the classpath<\/li><li>Support for reading and writing XML, if JAXB is on the classpath<\/li><li>Support for reading and writing JSON, if Jackson is on the classpath<\/li><\/ul>\n\n\n\n<p><strong>context:annotation-driven<\/strong><\/p>\n\n\n\n<p>&nbsp;it will resolve @Autowired and @Qualifier annotations for the beans which are already created and stored in the spring container.<\/p>\n\n\n\n<p>context:component-scan can also do the same job, but context:component-scan will also scan the packages for registering the beans to application context. context:annotation-config will not search for the beans registration, this will only activate the already registered beans in the context.<\/p>\n\n\n\n<h1 class=\"wp-block-heading\">Spring AOP<\/h1>\n\n\n\n<p>Why AOP?&nbsp;<\/p>\n\n\n\n<p>In object oriented programming there are many cross cutting concerns which are not specific to an object. These are required globally by the application&nbsp;<\/p>\n\n\n\n<p>Like logging<\/p>\n\n\n\n<p>Security<\/p>\n\n\n\n<p>Transactions<\/p>\n\n\n\n<p>If they are used in OOP then there are some problems&nbsp;<\/p>\n\n\n\n<ol class=\"wp-block-list\"><li>Too many relationships with these classes. &#8211; Classes are tightly coupled.<\/li><li>Code is required in all classes<\/li><li>Need to change code of every class using these common classes in case there is change.<\/li><\/ol>\n\n\n\n<p>How AOP Helps?<\/p>\n\n\n\n<ol class=\"wp-block-list\"><li>It is a common unit &#8211; provides configurable options where to call these common functions for each class.<\/li><li>There is low coupling<\/li><li>Code need not be changed in every class &#8211; just configuration.<\/li><\/ol>\n\n\n\n<p>Just like Triggers in SQL, Filters in Servlets.<\/p>\n\n\n\n<p>Installation&nbsp;<\/p>\n\n\n\n<p>Aspecjrtr.jar<\/p>\n\n\n\n<p>Aspectjrtweaver.jar<\/p>\n\n\n\n<p>Cglib.jar &#8211; used for generating classes by Spring. Spring modifies the original java source to add the Aspects at appropriate points and then generates a class. This library can add classes to a java program after the compilation phase as JAVA programs are linked during the runtime phase so this works.<\/p>\n\n\n\n<p>Asm.jar &#8211; cglib is built over it.<\/p>\n\n\n\n<p>Implementation<\/p>\n\n\n\n<ol class=\"wp-block-list\"><li>A class which defines cross cutting concerns must be labelled as <strong>@Aspect<\/strong><\/li><li>The functions of this class are called Advice. These can be called before\/after execution of any method in the spring container.<\/li><li>@Before execution ( public String getName() ) annotation over the Advice<\/li><\/ol>\n\n\n\n<p>@Before execution ( public String getName() ) &#8211; runs before every getName() of every class.<\/p>\n\n\n\n<p>How to restrict it to a particular class &#8211;&nbsp; @Before execution ( public String <strong>org.gaurav.Messenger.<\/strong>getName() )&nbsp;<\/p>\n\n\n\n<p>Pointcuts &#8211; are the points where advice are supposed to run like before getName().<\/p>\n\n\n\n<p>WildCards &#8211; help us to define PointCuts<br><\/p>\n\n\n\n<p>Advice gets executed only for user defined method execution. It has nothing to do with Springs initialization of Objects. Otherwise you could interfere with the framework.<\/p>\n\n\n\n<p>for all functions beginning with get &#8211;<\/p>\n\n\n\n<p>@Before(\u201cexecution ( public String get* )\u201d)&nbsp;<\/p>\n\n\n\n<p>for all functions beginning with get and all return types &#8211;<\/p>\n\n\n\n<p>@Before(\u201cexecution ( public * get* )\u201d)<\/p>\n\n\n\n<p>for all functions beginning with get, all return types &amp; all scopes &#8211;<\/p>\n\n\n\n<p>&nbsp;@Before(\u201c execution ( * get* )\u201d) &#8211; you could also use&nbsp; @Before execution (* * get* )<\/p>\n\n\n\n<p>for all functions beginning with get, all return types, all scopes &amp; <em>multiple arguments or if the function takes arguments<\/em><\/p>\n\n\n\n<p>&nbsp;@Before execution ( * get* (*) )&nbsp;<\/p>\n\n\n\n<p>for all functions beginning with get, all return types, all scopes &amp; <em>multiple arguments or no arguments<\/em><\/p>\n\n\n\n<p>&nbsp;@Before execution ( * get* (..) )&nbsp;<\/p>\n\n\n\n<p>for all functions beginning with get, all return types, all scopes &amp; <em>no arguments<\/em><\/p>\n\n\n\n<p>&nbsp;@Before execution ( * get* () )<\/p>\n\n\n\n<p>For all functions of a class&nbsp;<\/p>\n\n\n\n<p>&nbsp;@Before execution (*&nbsp; * org.gaurav.Messenger.*(..) )<\/p>\n\n\n\n<p>Or<\/p>\n\n\n\n<p>@PointCut (within ( org.gaurav.Messenger )<\/p>\n\n\n\n<p>For all functions of a package<\/p>\n\n\n\n<p>@PointCut (within ( org.gaurav.Messenger. )<\/p>\n\n\n\n<p>For all functions of a package &amp; sub packages<\/p>\n\n\n\n<p>@PointCut (within ( org.gaurav.Messenger.. )<\/p>\n\n\n\n<p>For all functions that have String args<\/p>\n\n\n\n<p>@Before( \u201cargs(String)\u201d)<\/p>\n\n\n\n<p>Apply multiple advices to various points?<br>We can use same annotation before two functions but spring gives a better way to manage<\/p>\n\n\n\n<p>@Before ( f3()&nbsp; )<\/p>\n\n\n\n<p>Public void f1(){ some lines here }&nbsp;&nbsp;<\/p>\n\n\n\n<p>@Before ( f3() )<\/p>\n\n\n\n<p>Public void f2(){ some lines here }&nbsp;&nbsp;<\/p>\n\n\n\n<p>@PointCut ( { EXP} )<\/p>\n\n\n\n<p>Public void f3(){ let this be empty }&nbsp;&nbsp;<\/p>\n\n\n\n<p>You can chain the pointcuts with conditions<\/p>\n\n\n\n<p>@Before ( EXP1 &amp;&amp; EXP2 )<\/p>\n\n\n\n<p>Both functions are dependent on the expression in f3() even if it is empty.<\/p>\n\n\n\n<p>*EXP could also be f1() too<\/p>\n\n\n\n<p>How to get a function name for which the advice is executing on?<\/p>\n\n\n\n<p>EXP<\/p>\n\n\n\n<p>Public void f1( JointCut jc )<\/p>\n\n\n\n<p>{<\/p>\n\n\n\n<p>jc.toString() &#8211; returns name of object.<\/p>\n\n\n\n<p>jc.getTarget() &#8211; returns object on which it is executing.<\/p>\n\n\n\n<p>}<\/p>\n\n\n\n<p>You can use joint cuts to restrict on how the advice should behave for a particular method.<\/p>\n\n\n\n<p>Types<\/p>\n\n\n\n<ol class=\"wp-block-list\"><li><strong>@Before<\/strong>&nbsp;<\/li><li><strong>@After<\/strong>&nbsp;<\/li><li><strong>@AfterReturning<\/strong>&nbsp;<\/li><li><strong>@Around<\/strong> &#8211; acts as both before and after<\/li><li><strong>@AfterThrowing<\/strong>&nbsp;<\/li><\/ol>\n\n\n\n<p>Fetch function param in the advice<\/p>\n\n\n\n<p>@Before(\u201cargs(name)\u201d)<\/p>\n\n\n\n<p>Public void f1( String name&nbsp; ) &#8211; f1 is advice . The exp tells AOP that it is argument of type String as it is mentioned in the signature &#8211; which is passed to the function.<\/p>\n\n\n\n<p>Execute and Fetch function param in the advice whose return type is String&nbsp;<\/p>\n\n\n\n<p>@AfterReturning(pointcut =\u201cargs(name)\u201d, returning=\u201dreturnString\u201d)<\/p>\n\n\n\n<p>Public void f1( String name, String&nbsp; returnString )&nbsp;<\/p>\n\n\n\n<p>Execute and&nbsp; Fetch function param in the advice whose return type is anything<\/p>\n\n\n\n<p>@AfterReturning(pointcut =\u201cargs(name)\u201d, returning=\u201dreturnString\u201d)<\/p>\n\n\n\n<p>Public void f1( String name, Object returnString )&nbsp;<\/p>\n\n\n\n<p>Similarly one can define what advice to run on what exception. @<\/p>\n\n\n\n<p>@Around&nbsp;<\/p>\n\n\n\n<p>Void f(PRoceedingJointCut p) {<\/p>\n\n\n\n<p>Code before<\/p>\n\n\n\n<p>p.proceed();<\/p>\n\n\n\n<p>Code after<\/p>\n\n\n\n<p>}<\/p>\n\n\n\n<p>Custom Annotations<\/p>\n\n\n\n<ol class=\"wp-block-list\"><li>Define an interface<\/li><li>In the spring.xml&nbsp;<\/li><\/ol>\n\n\n\n<p>@Before \u201c@annotation(org.gaurav.mypackage.LoggerCustom)\u201d )<\/p>\n\n\n\n<p>Void advice (){}<\/p>\n\n\n\n<p>3. Using it&nbsp;&nbsp;<\/p>\n\n\n\n<p>@LoggerCustom<br>Void f1 ()<\/p>\n\n\n\n<p>All these annotations can be turned to XML binding as well<\/p>\n\n\n\n<p>Spring AOP works on the concept of Proxy objects<\/p>\n\n\n\n<p>Class abc {<\/p>\n\n\n\n<p>Public String f1 {<\/p>\n\n\n\n<p>return \u201cHI\u201d;<\/p>\n\n\n\n<p>}<\/p>\n\n\n\n<p>}<\/p>\n\n\n\n<p>Class abcProvider extends abc {}<\/p>\n\n\n\n<p>Public String f1 {<\/p>\n\n\n\n<p>Run before advice() &#8211; injects code based on annotation we provided to AOP<\/p>\n\n\n\n<p>return \u201cHI\u201d;<\/p>\n\n\n\n<p>Run before advice() &#8211; injects code based on annotation we provided to AOP<\/p>\n\n\n\n<p>}<\/p>\n\n\n\n<p>}<\/p>\n\n\n\n<h1 class=\"wp-block-heading\">Spring Data<\/h1>\n\n\n\n<p>Spring allows connecting to several databases. Just like JDBC, it also has certain classes that can help to make work easier.<\/p>\n\n\n\n<p>To make a JDBC with Spring class<\/p>\n\n\n\n<p>One can use the same concepts except that Spring can inject the Data Source at run time from the one defined in configuration.<\/p>\n\n\n\n<p>To further the maintainability and availability&nbsp;<\/p>\n\n\n\n<p>One can use JDBCTemplate.<\/p>\n\n\n\n<p>JDBCTemplatejust needs a DataSource object as a parameter. It takes care of the rest like opening the connection, closing the connection, executing the query etc.<\/p>\n\n\n\n<p>The data source object created in \u201cJDBC with Spring class\u201d can be used and so only a query needs to be set. This does the work of executing the query.<\/p>\n\n\n\n<p>DataSource Is class of type org.springframework.jdbc.datasource.DriverManagerDataSource<\/p>\n\n\n\n<p>To execute Query&nbsp;<\/p>\n\n\n\n<p>We use function jdbcTemplate.query(&#8230;..) ,jdbcTemplate.queryForInt(&#8230;..), jdbcTemplate.queryForObject(&#8230;..)<\/p>\n\n\n\n<p><br>The params are like Query String, PArameters, RowMapper<\/p>\n\n\n\n<p>RowMapper is an interface which needs to be implemented in a class.<\/p>\n\n\n\n<p>It maps Resultset to a row\/ user defined object.<\/p>\n\n\n\n<p>Like if you are obtaining Student objects in ResultSet (which doesn&#8217;t understand the info it is carrying)&nbsp;<\/p>\n\n\n\n<p>You can easily map the ResultSet data of each row into one object of Student.&nbsp;<\/p>\n\n\n\n<p>There are various jdbcTemplate classes<\/p>\n\n\n\n<ol class=\"wp-block-list\"><li>jdbcTemplate &#8211; for question mark parameters<\/li><li>NamedParameterJdbTemplate &#8211; to be used for named parameters.<\/li><li>SimpleJdbcTemplate &#8211; Can be used for both the named and question mark parameter<\/li><\/ol>\n\n\n\n<p>A good way to directly use the jdbc template without having to provide many lines of code in the class is to&nbsp;<\/p>\n\n\n\n<p>Extends JdbcDaoSupport \/ SimpleJdbcDaoSupport \/..<\/p>\n\n\n\n<p>These classes have no functions to extend but a member variable \u201cDataSource\u201d which needs to be initialized.<\/p>\n\n\n\n<p>The class extending this needs to be provide a data source in bean and then you get the jdbc template prepared object using a getter<\/p>\n\n\n\n<p>this.getJdbcTemplate()<\/p>\n\n\n\n<p>Integrate with Hibernate<\/p>\n\n\n\n<p>One can import the hibernate libraries and import them to integrate the Hibernate with Spring.<\/p>\n\n\n\n<p>Define a SessionFactory bean with required properties&nbsp; &#8211; dataSource, packagesToScan(for any data models) , define hibernate properties (dialect etc).<br><br>One does not need a seperate Hibernate.cfg here because spring.xml can be used for the same purpose.<\/p>\n\n\n\n<p>Once SessionFactory which is&nbsp; a heavy object is constructed &#8211; this needs to be done only once &#8211; it will be called in any transaction to Open session and execute the query.<\/p>\n<!--themify_builder_content-->\n<div id=\"themify_builder_content-1802\" data-postid=\"1802\" class=\"themify_builder_content themify_builder_content-1802 themify_builder tf_clear\">\n    <\/div>\n<!--\/themify_builder_content-->\n","protected":false},"excerpt":{"rendered":"<p>Spring Core Spring has many parts. Core is about dependency injection \/version where we have to decouple the classes. Spring has containers just like a Tomcat has called a container. It manages the lifecycle of an object mentioned in XML similar to Tomcat. This works based on Factory Pattern &#8211; A factory class can instantiate [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_jetpack_memberships_contains_paid_content":false,"footnotes":""},"categories":[97],"tags":[],"class_list":["post-1802","post","type-post","status-publish","format-standard","hentry","category-tech-learnings","has-post-title","has-post-date","has-post-category","has-post-tag","has-post-comment","has-post-author",""],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v24.3 - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>Spring Framework &#187; Gaurav Wadhwani<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/gauravw.com\/blog\/2021\/04\/spring-framework\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Spring Framework &#187; Gaurav Wadhwani\" \/>\n<meta property=\"og:description\" content=\"Spring Core Spring has many parts. Core is about dependency injection \/version where we have to decouple the classes. Spring has containers just like a Tomcat has called a container. It manages the lifecycle of an object mentioned in XML similar to Tomcat. This works based on Factory Pattern &#8211; A factory class can instantiate [&hellip;]\" \/>\n<meta property=\"og:url\" content=\"https:\/\/gauravw.com\/blog\/2021\/04\/spring-framework\/\" \/>\n<meta property=\"og:site_name\" content=\"Gaurav Wadhwani\" \/>\n<meta property=\"article:published_time\" content=\"2021-04-10T12:17:03+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2021-04-10T12:17:06+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/lh3.googleusercontent.com\/VM-wiulxP7iLUy7GDXVzajM2K4zWa9WjgBhUfHbkapwx07uiA4wmuarDeqJuXPj9SMzk9g992xf1nSwMORqmwaAJibCg-a1N1gjH5wJFYUVdtGTMoawpGccmJ4UKHwc0rpViTbUP\" \/>\n<meta name=\"author\" content=\"Gaurav Wadhwani\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Gaurav Wadhwani\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"14 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\/\/gauravw.com\/blog\/2021\/04\/spring-framework\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/gauravw.com\/blog\/2021\/04\/spring-framework\/\"},\"author\":{\"name\":\"Gaurav Wadhwani\",\"@id\":\"https:\/\/gauravw.com\/blog\/#\/schema\/person\/9a05a9c3487f35f6b4577c6956cf252e\"},\"headline\":\"Spring Framework\",\"datePublished\":\"2021-04-10T12:17:03+00:00\",\"dateModified\":\"2021-04-10T12:17:06+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/gauravw.com\/blog\/2021\/04\/spring-framework\/\"},\"wordCount\":3338,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\/\/gauravw.com\/blog\/#\/schema\/person\/9a05a9c3487f35f6b4577c6956cf252e\"},\"image\":{\"@id\":\"https:\/\/gauravw.com\/blog\/2021\/04\/spring-framework\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/lh3.googleusercontent.com\/VM-wiulxP7iLUy7GDXVzajM2K4zWa9WjgBhUfHbkapwx07uiA4wmuarDeqJuXPj9SMzk9g992xf1nSwMORqmwaAJibCg-a1N1gjH5wJFYUVdtGTMoawpGccmJ4UKHwc0rpViTbUP\",\"articleSection\":[\"Tech Learnings\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\/\/gauravw.com\/blog\/2021\/04\/spring-framework\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/gauravw.com\/blog\/2021\/04\/spring-framework\/\",\"url\":\"https:\/\/gauravw.com\/blog\/2021\/04\/spring-framework\/\",\"name\":\"Spring Framework &#187; Gaurav Wadhwani\",\"isPartOf\":{\"@id\":\"https:\/\/gauravw.com\/blog\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/gauravw.com\/blog\/2021\/04\/spring-framework\/#primaryimage\"},\"image\":{\"@id\":\"https:\/\/gauravw.com\/blog\/2021\/04\/spring-framework\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/lh3.googleusercontent.com\/VM-wiulxP7iLUy7GDXVzajM2K4zWa9WjgBhUfHbkapwx07uiA4wmuarDeqJuXPj9SMzk9g992xf1nSwMORqmwaAJibCg-a1N1gjH5wJFYUVdtGTMoawpGccmJ4UKHwc0rpViTbUP\",\"datePublished\":\"2021-04-10T12:17:03+00:00\",\"dateModified\":\"2021-04-10T12:17:06+00:00\",\"breadcrumb\":{\"@id\":\"https:\/\/gauravw.com\/blog\/2021\/04\/spring-framework\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/gauravw.com\/blog\/2021\/04\/spring-framework\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/gauravw.com\/blog\/2021\/04\/spring-framework\/#primaryimage\",\"url\":\"https:\/\/lh3.googleusercontent.com\/VM-wiulxP7iLUy7GDXVzajM2K4zWa9WjgBhUfHbkapwx07uiA4wmuarDeqJuXPj9SMzk9g992xf1nSwMORqmwaAJibCg-a1N1gjH5wJFYUVdtGTMoawpGccmJ4UKHwc0rpViTbUP\",\"contentUrl\":\"https:\/\/lh3.googleusercontent.com\/VM-wiulxP7iLUy7GDXVzajM2K4zWa9WjgBhUfHbkapwx07uiA4wmuarDeqJuXPj9SMzk9g992xf1nSwMORqmwaAJibCg-a1N1gjH5wJFYUVdtGTMoawpGccmJ4UKHwc0rpViTbUP\"},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/gauravw.com\/blog\/2021\/04\/spring-framework\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/gauravw.com\/blog\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Spring Framework\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/gauravw.com\/blog\/#website\",\"url\":\"https:\/\/gauravw.com\/blog\/\",\"name\":\"Gaurav Wadhwani\",\"description\":\"Where I write \/ scribble\",\"publisher\":{\"@id\":\"https:\/\/gauravw.com\/blog\/#\/schema\/person\/9a05a9c3487f35f6b4577c6956cf252e\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/gauravw.com\/blog\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":[\"Person\",\"Organization\"],\"@id\":\"https:\/\/gauravw.com\/blog\/#\/schema\/person\/9a05a9c3487f35f6b4577c6956cf252e\",\"name\":\"Gaurav Wadhwani\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/gauravw.com\/blog\/#\/schema\/person\/image\/\",\"url\":\"https:\/\/secure.gravatar.com\/avatar\/88929454012064ffbe95370287faa36b?s=96&d=mm&r=g\",\"contentUrl\":\"https:\/\/secure.gravatar.com\/avatar\/88929454012064ffbe95370287faa36b?s=96&d=mm&r=g\",\"caption\":\"Gaurav Wadhwani\"},\"logo\":{\"@id\":\"https:\/\/gauravw.com\/blog\/#\/schema\/person\/image\/\"},\"sameAs\":[\"http:\/\/gauravw.com\"]}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Spring Framework &#187; Gaurav Wadhwani","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/gauravw.com\/blog\/2021\/04\/spring-framework\/","og_locale":"en_US","og_type":"article","og_title":"Spring Framework &#187; Gaurav Wadhwani","og_description":"Spring Core Spring has many parts. Core is about dependency injection \/version where we have to decouple the classes. Spring has containers just like a Tomcat has called a container. It manages the lifecycle of an object mentioned in XML similar to Tomcat. This works based on Factory Pattern &#8211; A factory class can instantiate [&hellip;]","og_url":"https:\/\/gauravw.com\/blog\/2021\/04\/spring-framework\/","og_site_name":"Gaurav Wadhwani","article_published_time":"2021-04-10T12:17:03+00:00","article_modified_time":"2021-04-10T12:17:06+00:00","og_image":[{"url":"https:\/\/lh3.googleusercontent.com\/VM-wiulxP7iLUy7GDXVzajM2K4zWa9WjgBhUfHbkapwx07uiA4wmuarDeqJuXPj9SMzk9g992xf1nSwMORqmwaAJibCg-a1N1gjH5wJFYUVdtGTMoawpGccmJ4UKHwc0rpViTbUP","type":"","width":"","height":""}],"author":"Gaurav Wadhwani","twitter_card":"summary_large_image","twitter_misc":{"Written by":"Gaurav Wadhwani","Est. reading time":"14 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/gauravw.com\/blog\/2021\/04\/spring-framework\/#article","isPartOf":{"@id":"https:\/\/gauravw.com\/blog\/2021\/04\/spring-framework\/"},"author":{"name":"Gaurav Wadhwani","@id":"https:\/\/gauravw.com\/blog\/#\/schema\/person\/9a05a9c3487f35f6b4577c6956cf252e"},"headline":"Spring Framework","datePublished":"2021-04-10T12:17:03+00:00","dateModified":"2021-04-10T12:17:06+00:00","mainEntityOfPage":{"@id":"https:\/\/gauravw.com\/blog\/2021\/04\/spring-framework\/"},"wordCount":3338,"commentCount":0,"publisher":{"@id":"https:\/\/gauravw.com\/blog\/#\/schema\/person\/9a05a9c3487f35f6b4577c6956cf252e"},"image":{"@id":"https:\/\/gauravw.com\/blog\/2021\/04\/spring-framework\/#primaryimage"},"thumbnailUrl":"https:\/\/lh3.googleusercontent.com\/VM-wiulxP7iLUy7GDXVzajM2K4zWa9WjgBhUfHbkapwx07uiA4wmuarDeqJuXPj9SMzk9g992xf1nSwMORqmwaAJibCg-a1N1gjH5wJFYUVdtGTMoawpGccmJ4UKHwc0rpViTbUP","articleSection":["Tech Learnings"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/gauravw.com\/blog\/2021\/04\/spring-framework\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/gauravw.com\/blog\/2021\/04\/spring-framework\/","url":"https:\/\/gauravw.com\/blog\/2021\/04\/spring-framework\/","name":"Spring Framework &#187; Gaurav Wadhwani","isPartOf":{"@id":"https:\/\/gauravw.com\/blog\/#website"},"primaryImageOfPage":{"@id":"https:\/\/gauravw.com\/blog\/2021\/04\/spring-framework\/#primaryimage"},"image":{"@id":"https:\/\/gauravw.com\/blog\/2021\/04\/spring-framework\/#primaryimage"},"thumbnailUrl":"https:\/\/lh3.googleusercontent.com\/VM-wiulxP7iLUy7GDXVzajM2K4zWa9WjgBhUfHbkapwx07uiA4wmuarDeqJuXPj9SMzk9g992xf1nSwMORqmwaAJibCg-a1N1gjH5wJFYUVdtGTMoawpGccmJ4UKHwc0rpViTbUP","datePublished":"2021-04-10T12:17:03+00:00","dateModified":"2021-04-10T12:17:06+00:00","breadcrumb":{"@id":"https:\/\/gauravw.com\/blog\/2021\/04\/spring-framework\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/gauravw.com\/blog\/2021\/04\/spring-framework\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/gauravw.com\/blog\/2021\/04\/spring-framework\/#primaryimage","url":"https:\/\/lh3.googleusercontent.com\/VM-wiulxP7iLUy7GDXVzajM2K4zWa9WjgBhUfHbkapwx07uiA4wmuarDeqJuXPj9SMzk9g992xf1nSwMORqmwaAJibCg-a1N1gjH5wJFYUVdtGTMoawpGccmJ4UKHwc0rpViTbUP","contentUrl":"https:\/\/lh3.googleusercontent.com\/VM-wiulxP7iLUy7GDXVzajM2K4zWa9WjgBhUfHbkapwx07uiA4wmuarDeqJuXPj9SMzk9g992xf1nSwMORqmwaAJibCg-a1N1gjH5wJFYUVdtGTMoawpGccmJ4UKHwc0rpViTbUP"},{"@type":"BreadcrumbList","@id":"https:\/\/gauravw.com\/blog\/2021\/04\/spring-framework\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/gauravw.com\/blog\/"},{"@type":"ListItem","position":2,"name":"Spring Framework"}]},{"@type":"WebSite","@id":"https:\/\/gauravw.com\/blog\/#website","url":"https:\/\/gauravw.com\/blog\/","name":"Gaurav Wadhwani","description":"Where I write \/ scribble","publisher":{"@id":"https:\/\/gauravw.com\/blog\/#\/schema\/person\/9a05a9c3487f35f6b4577c6956cf252e"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/gauravw.com\/blog\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":["Person","Organization"],"@id":"https:\/\/gauravw.com\/blog\/#\/schema\/person\/9a05a9c3487f35f6b4577c6956cf252e","name":"Gaurav Wadhwani","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/gauravw.com\/blog\/#\/schema\/person\/image\/","url":"https:\/\/secure.gravatar.com\/avatar\/88929454012064ffbe95370287faa36b?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/88929454012064ffbe95370287faa36b?s=96&d=mm&r=g","caption":"Gaurav Wadhwani"},"logo":{"@id":"https:\/\/gauravw.com\/blog\/#\/schema\/person\/image\/"},"sameAs":["http:\/\/gauravw.com"]}]}},"jetpack_sharing_enabled":true,"jetpack_featured_media_url":"","builder_content":"","_links":{"self":[{"href":"https:\/\/gauravw.com\/blog\/wp-json\/wp\/v2\/posts\/1802","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/gauravw.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/gauravw.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/gauravw.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/gauravw.com\/blog\/wp-json\/wp\/v2\/comments?post=1802"}],"version-history":[{"count":1,"href":"https:\/\/gauravw.com\/blog\/wp-json\/wp\/v2\/posts\/1802\/revisions"}],"predecessor-version":[{"id":1804,"href":"https:\/\/gauravw.com\/blog\/wp-json\/wp\/v2\/posts\/1802\/revisions\/1804"}],"wp:attachment":[{"href":"https:\/\/gauravw.com\/blog\/wp-json\/wp\/v2\/media?parent=1802"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/gauravw.com\/blog\/wp-json\/wp\/v2\/categories?post=1802"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/gauravw.com\/blog\/wp-json\/wp\/v2\/tags?post=1802"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}