Use protected instead of private for member variables - spring

I always got problems with the private variable declaration.
For example FlatFileItemWrite. I would like to extend these class and overwrite the 'doRead' method. This would not work because some of the used variables are declared private. This leads to copying the complete code in an own class for overwriting one method.
Sometime even this does not work because the class extends an other class which has variables declared visible only for the same package. Then you need to copy this class also.
Then I will miss updates in the original classes with new versions. So would it not be better to use protected instead?
I can imaging only a very few reasons to use private instead of protected. For my own programs this is not an issue, I could change it on demand. But for a framework it is a pain.
with kind regards
Torsten

If something is declared private within the Spring framework (or any framework for that matter), it's not considered part of the public API. Because of that, you really shouldn't be looking to work with it directly. Doing so really means you're forking the framework and risking not being able to upgrade seamlessly.
As the project lead for Spring Batch, I'd be interested in hearing what you had to do with the FlatFileItemWriter that required you to change things that are marked private.

If the idea behind the framework was to override or extend these methods, they should have been written as being public. (be careful if a framework does not provide these methods or properties as public, since it might depend on them working in a specific way. this would be the primary reason for them being private i can think of. the secondary being that they don't matter outside that class.)
In some cases, you might not need to copy the entire class, but simply inheriting or extending it might be enough.

I'm also looking to extend certain ItemReaders/ItemWriters to support decryption/encryption on i/o. For example, I'd like to extend StaxEventItemReaderStaxEventItemReader in order to read an encrypted stream from the resource, but the FragmentEventReader is private, so I'm unable to wrap its XMLEventReader's InputStream in a decrypter.
I faced the same issue with FlatFileItemWriter.

Related

Using .Net Core Identity with generic repository

So I'm trying to get my head around this for a while now, but I don't seem to succeed. In my application I'm using a generic repository with Entity Framework Core.
Hence my Repository always expect that it's accessed from a class who's BaseEntity or has inherited from that certain class.
Now I want to implement .Net Core Identity with it. But My User class is inheriting from BaseEntity. But I'd also need it to inherit from Identity in order to make it work I guess. How am I able to still use Identity?
C# only supports single inheritance. You cannot inherit from two different classes. Additionally your Identity user class, must inherit from IdentityUser. You have no choice in that. As a result, the best you can do is make your user class and the rest of your entity classes implement the same interface, i.e. IEntity. Then, instead of constraining your generic type as BaseEntity, use IEntity instead.
Of course, this means you will incur a bit of code duplication as you'll have to implement IEntity separately on both BaseEntity and your user class. However, that is unavoidable.

Executing extension before SpringExtension

I'm trying to implement integration testing in my app and have test class like that:
#ExtendWith(value={MyDockerExtension.class})
#ExtendWith(value={SpringExtension.class})
#WebAppConfiguration
#ContextConfiguration(classes={...})
#TestInstance(TestInstance.LifeCycle.PER_CLASS)
public class TestClass{ ... }
Is there any way to make MyDockerExtension execute some code, before whole SpringExtension start working and generate whole Context with Configurationc classes?
I've heard that order in which we declare extensions is the key, but sadly MyDockerExtension that implements BeforeAllCallback, AfterAllCallback executes right before test method and after whole context is loaded. In that situation it's to late to start containers with docker, becuase since whole context is loaded my app already tried to connect to the container.
At first I was skeptical about the order being fixed but you're correct:
Extensions registered declaratively via #ExtendWith will be executed in the order in which they are declared in the source code.
Regarding the MyDockerExtension, you may want to look at the extension point TestInstancePostProcessor, which is called before #BeforeAll. SpringExtension implements it and I guess it's there where it sets up the application context. If you also implement it, you should be able to act before it does.

Example of new abstract new abstract CreateContainerExtension method in 7.1.0.172-pre

Does anyone have an example of the new abstract method CreateContainerExtension that is in Prism.Wpf 7.1.0.172-pre? We are using the common service locator and have essentially bypassed IOC in Prism because we need to resolve things before the Bootstrapper has run.
You should remember that Prism is open source and the source code is in itself a form of documentation.
If you're using the classic Bootstrapper, you'll notice that it has been deprecated in favor of PrismApplication. Since your question is extremely vague as to what container you're even trying to use, it's impossible to tell exactly which Container Extension to use, but I will provide an example using Unity for your reference.
Whether you look at the UnityBootstraper or the Unity PrismApplication, you'll see that it simply returns an instance of the UnityContainerExtension.
protected override IContainerExtension CreateContainerExtension()
{
return new UnityContainerExtension();
}

Testing spring repositories

In the Spring Data I have found very helpful interface called JpaRepository. Because I need more functionality I decided to create my own interface of repository:
public interface BaseRepository<T, ID extends Serializable>
extends JpaRepository<T, ID> {
public <TA, TV> int deleteBy(SingularAttribute<T, TA> attr, TV val);
}
As you can see this is a generic interface. It works fine, but I would like to know how I can test it? Of course I can write integration test for each concrete repository but I am looking for better way.
As usual with testing, you should make sure you know what you're testing. Find answers to these questions:
Do you want to test the underlying database?
Do you want to test the Spring Data repository connector for this respository?
Do you want to test whether your code calls the correct methods on the interface?
Doing #1 is useless: The database vendor has already run thousands of tests on its product. There is rarely a reason to do this effort again.
Doing #2 is useless unless you suspect a bug in the code for Spring Data.
Which leaves us with #3. Use a mocking framework to make sure the method is called at the appropriate places (and maybe check the arguments, too).
That way, you can make sure your code behaves correctly.
If you notice the framework throwing errors or you notice that objects aren't deleted correctly, you can add more tests. But most of the time, this won't happen because of bugs in the database or Spring Data. Instead, your code won't call deleteBy() or it will call the method with the wrong arguments.

Spring overwriting controller

I provide a highly customisable application to my clients which is working totally by itself. But If one my client wants to overwrite any Controller, I want to replace my implementation by theirs. However just overwriting the controller causes an ambiguous definition of mappings.
I have been using Component Scanning to load beans.
The potential solutions came to my mind are:
Using component scanner with excluding by a custom filter? (This seems not so easy)
Using a xxxxPostProcessor to remove some beans? (How?)
Any help?
If I got your Question properly,
You can differ implementation by changing URL to particular Implementation name
Say Telecom is interface and AirtelImpl and RelianceImpl are Controllers then
Your request mapping
#RequestMapping(value= "/airtel/doBilling")
#RequestMapping(value= "/reliance/doBilling")
In this way, Implementation flow will differ.
I have followed these steps:
Created a custom annotation: #Devoted
Created a custom ImportBeanDefinitionRegistrar. Iterated already registered bean definitions to find out `#Devoted #Controller's and removed them.
Based on a request I will provide implementation details.

Resources